*/
package org.openhab.binding.alarmdecoder.internal.actions;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.alarmdecoder.internal.handler.ADBridgeHandler;
*/
@ThingActionsScope(name = "alarmdecoder")
@NonNullByDefault
-public class BridgeActions implements ThingActions, IBridgeActions {
+public class BridgeActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(BridgeActions.class);
/**
* Reboot thing action
*/
- @Override
- @RuleAction(label = "Reboot", description = "Reboot the Alarm Decoder device")
+ @RuleAction(label = "reboot the device", description = "Reboot the Alarm Decoder device.")
public void reboot() {
ADBridgeHandler bridge = this.bridge;
if (bridge != null) {
// Static method for Rules DSL backward compatibility
public static void reboot(@Nullable ThingActions actions) {
- // if (actions instanceof BridgeActions) {
- // ((BridgeActions) actions).reboot();
- // } else {
- // throw new IllegalArgumentException("Instance is not a BridgeActions class.");
- // }
- invokeMethodOf(actions).reboot(); // Remove and uncomment above when core issue #1536 is fixed
- }
-
- /**
- * This is only necessary to work around a bug in openhab-core (issue #1536). It should be removed once that is
- * resolved.
- */
- private static IBridgeActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(BridgeActions.class.getName())) {
- if (actions instanceof IBridgeActions) {
- return (IBridgeActions) actions;
- } else {
- return (IBridgeActions) Proxy.newProxyInstance(IBridgeActions.class.getClassLoader(),
- new Class[] { IBridgeActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
+ if (actions instanceof BridgeActions) {
+ ((BridgeActions) actions).reboot();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of BridgeActions");
}
- throw new IllegalArgumentException("Actions is not an instance of BridgeActions");
}
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.alarmdecoder.internal.actions;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * The {@link IBridgeActions} defines the interface for all thing actions supported by the bridges.
- * This is only necessary to work around a bug in openhab-core (issue #1536). It should be removed once that is
- * resolved.
- *
- * @author Bob Adair - Initial contribution
- *
- */
-@NonNullByDefault
-public interface IBridgeActions {
-
- public void reboot();
-}
*/
package org.openhab.binding.astro.internal.action;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
import java.time.ZonedDateTime;
import javax.measure.quantity.Angle;
import org.slf4j.LoggerFactory;
/**
- * The {AstroActions } defines rule actions for the Astro binding.
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof AstroActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link AstroActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
+ * Defines the automation thing actions for the Astro binding.
*
* @author Gaël L'hopital - Initial contribution
*/
@ThingActionsScope(name = "astro")
@NonNullByDefault
-public class AstroActions implements ThingActions, IAstroActions {
+public class AstroActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(AstroActions.class);
protected @Nullable AstroThingHandler handler;
@Override
public @Nullable ThingHandler getThingHandler() {
- return this.handler;
+ return handler;
}
- @Override
- @RuleAction(label = "Astro : Get Azimuth", description = "Get the azimuth of the sun for a given time")
+ @RuleAction(label = "get the azimuth", description = "Get the azimuth for a given time.")
public @Nullable @ActionOutput(name = "getAzimuth", label = "Azimuth", type = "org.openhab.core.library.types.QuantityType<javax.measure.quantity.Angle>") QuantityType<Angle> getAzimuth(
@ActionInput(name = "date", label = "Date", required = false, description = "Considered date") @Nullable ZonedDateTime date) {
logger.debug("Astro action 'getAzimuth' called");
return null;
}
- @Override
- @RuleAction(label = "Astro : Get Elevation", description = "Get the Elevation of the sun for a given time")
+ @RuleAction(label = "get the elevation", description = "Get the elevation for a given time.")
public @Nullable @ActionOutput(name = "getElevation", label = "Elevation", type = "org.openhab.core.library.types.QuantityType<javax.measure.quantity.Angle>") QuantityType<Angle> getElevation(
@ActionInput(name = "date", label = "Date", required = false, description = "Considered date") @Nullable ZonedDateTime date) {
logger.debug("Astro action 'getElevation' called");
return null;
}
- @Override
- @RuleAction(label = "Sun : Get Event Time", description = "Get the date time of a given planet event")
+ @RuleAction(label = "get the date time of a sun event", description = "Get the date time of a sun event.")
public @Nullable @ActionOutput(name = "getEventTime", type = "java.time.ZonedDateTime") ZonedDateTime getEventTime(
@ActionInput(name = "phaseName", label = "Phase", required = true, description = "Requested phase") String phaseName,
@ActionInput(name = "date", label = "Date", required = false, description = "Considered date") @Nullable ZonedDateTime date,
public static @Nullable QuantityType<Angle> getElevation(@Nullable ThingActions actions,
@Nullable ZonedDateTime date) {
- return invokeMethodOf(actions).getElevation(date);
+ if (actions instanceof AstroActions) {
+ return ((AstroActions) actions).getElevation(date);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of AstroActions");
+ }
}
public static @Nullable QuantityType<Angle> getAzimuth(@Nullable ThingActions actions,
@Nullable ZonedDateTime date) {
- return invokeMethodOf(actions).getAzimuth(date);
- }
-
- public static @Nullable ZonedDateTime getEventTime(@Nullable ThingActions actions, @Nullable String phaseName,
- @Nullable ZonedDateTime date, @Nullable String moment) {
- if (phaseName != null) {
- return invokeMethodOf(actions).getEventTime(phaseName, date, moment);
+ if (actions instanceof AstroActions) {
+ return ((AstroActions) actions).getAzimuth(date);
} else {
- throw new IllegalArgumentException("phaseName can not be null");
+ throw new IllegalArgumentException("Actions is not an instance of AstroActions");
}
}
- private static IAstroActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(AstroActions.class.getName())) {
- if (actions instanceof IAstroActions) {
- return (IAstroActions) actions;
+ public static @Nullable ZonedDateTime getEventTime(@Nullable ThingActions actions, @Nullable String phaseName,
+ @Nullable ZonedDateTime date, @Nullable String moment) {
+ if (actions instanceof AstroActions) {
+ if (phaseName != null) {
+ return ((AstroActions) actions).getEventTime(phaseName, date, moment);
} else {
- return (IAstroActions) Proxy.newProxyInstance(IAstroActions.class.getClassLoader(),
- new Class[] { IAstroActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
+ throw new IllegalArgumentException("phaseName can not be null");
}
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of AstroActions");
}
- throw new IllegalArgumentException("Actions is not an instance of AstroActions");
}
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.astro.internal.action;
-
-import java.time.ZonedDateTime;
-
-import javax.measure.quantity.Angle;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.library.types.QuantityType;
-
-/**
- * The {@link IAstroActions} defines the interface for all thing actions supported by the binding.
- *
- * @author Gaël L'hopital - Initial contribution
- */
-@NonNullByDefault
-public interface IAstroActions {
- public @Nullable ZonedDateTime getEventTime(String phaseName, @Nullable ZonedDateTime date,
- @Nullable String moment);
-
- public @Nullable QuantityType<Angle> getAzimuth(@Nullable ZonedDateTime date);
-
- public @Nullable QuantityType<Angle> getElevation(@Nullable ZonedDateTime date);
-}
*/
package org.openhab.binding.automower.internal.actions;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.automower.internal.things.AutomowerCommand;
*/
@ThingActionsScope(name = "automower")
@NonNullByDefault
-public class AutomowerActions implements ThingActions, IAutomowerActions {
+public class AutomowerActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(AutomowerActions.class);
private @Nullable AutomowerHandler handler;
return handler;
}
- @Override
@RuleAction(label = "@text/action-start-label", description = "@text/action-start-desc")
public void start(
@ActionInput(name = "duration", label = "@text/action-input-duration-label", description = "@text/action-input-duration-desc") int durationMin) {
}
public static void start(@Nullable ThingActions actions, int durationMin) {
- invokeMethodOf(actions).start(durationMin);
+ if (actions instanceof AutomowerActions) {
+ ((AutomowerActions) actions).start(durationMin);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of AutomowerActions");
+ }
}
- @Override
@RuleAction(label = "@text/action-pause-label", description = "@text/action-pause-desc")
public void pause() {
AutomowerHandler automowerHandler = handler;
}
public static void pause(@Nullable ThingActions actions) {
- invokeMethodOf(actions).pause();
+ if (actions instanceof AutomowerActions) {
+ ((AutomowerActions) actions).pause();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of AutomowerActions");
+ }
}
- @Override
@RuleAction(label = "@text/action-parkuntilnextschedule-label", description = "@text/action-parkuntilnextschedule-desc")
public void parkUntilNextSchedule() {
AutomowerHandler automowerHandler = handler;
}
public static void parkUntilNextSchedule(@Nullable ThingActions actions) {
- invokeMethodOf(actions).parkUntilNextSchedule();
+ if (actions instanceof AutomowerActions) {
+ ((AutomowerActions) actions).parkUntilNextSchedule();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of AutomowerActions");
+ }
}
- @Override
@RuleAction(label = "@text/action-parkuntilfurthernotice-label", description = "@text/action-parkuntilfurthernotice-desc")
public void parkUntilFurtherNotice() {
AutomowerHandler automowerHandler = handler;
}
public static void parkUntilFurtherNotice(@Nullable ThingActions actions) {
- invokeMethodOf(actions).parkUntilFurtherNotice();
+ if (actions instanceof AutomowerActions) {
+ ((AutomowerActions) actions).parkUntilFurtherNotice();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of AutomowerActions");
+ }
}
- @Override
@RuleAction(label = "@text/action-park-label", description = "@text/action-park-desc")
public void park(
@ActionInput(name = "duration", label = "@text/action-input-duration-label", description = "@text/action-input-duration-desc") int durationMin) {
}
public static void park(@Nullable ThingActions actions, int durationMin) {
- invokeMethodOf(actions).park(durationMin);
+ if (actions instanceof AutomowerActions) {
+ ((AutomowerActions) actions).park(durationMin);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of AutomowerActions");
+ }
}
- @Override
@RuleAction(label = "@text/action-resumeschedule-label", description = "@text/action-resumeschedule-desc")
public void resumeSchedule() {
AutomowerHandler automowerHandler = handler;
}
public static void resumeSchedule(@Nullable ThingActions actions) {
- invokeMethodOf(actions).resumeSchedule();
- }
-
- private static IAutomowerActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(AutomowerActions.class.getName())) {
- if (actions instanceof AutomowerActions) {
- return (IAutomowerActions) actions;
- } else {
- return (IAutomowerActions) Proxy.newProxyInstance(IAutomowerActions.class.getClassLoader(),
- new Class[] { IAutomowerActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
+ if (actions instanceof AutomowerActions) {
+ ((AutomowerActions) actions).resumeSchedule();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of AutomowerActions");
}
- throw new IllegalArgumentException("Actions is not an instance of IAutomowerActions");
}
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.automower.internal.actions;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * Actions that can be executed for an automower
- *
- * @author Markus Pfleger - Initial contribution
- */
-@NonNullByDefault
-public interface IAutomowerActions {
-
- void resumeSchedule();
-
- void park(int durationMin);
-
- void parkUntilFurtherNotice();
-
- void parkUntilNextSchedule();
-
- void pause();
-
- void start(int durationMin);
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.avmfritz.actions;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.avmfritz.internal.actions.IAVMFritzHeatingActions;
-import org.openhab.binding.avmfritz.internal.handler.AVMFritzHeatingActionsHandler;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link AVMFritzHeatingActions} defines thing actions for heating devices / groups of the avmfritz binding.
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-@ThingActionsScope(name = "avmfritz")
-@NonNullByDefault
-public class AVMFritzHeatingActions implements ThingActions, IAVMFritzHeatingActions {
-
- private final Logger logger = LoggerFactory.getLogger(AVMFritzHeatingActions.class);
-
- private @Nullable AVMFritzHeatingActionsHandler handler;
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- this.handler = (AVMFritzHeatingActionsHandler) handler;
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return handler;
- }
-
- @Override
- @RuleAction(label = "@text/setBoostModeModeActionLabel", description = "@text/setBoostModeActionDescription")
- public void setBoostMode(
- @ActionInput(name = "Duration", label = "@text/setBoostModeDurationInputLabel", description = "@text/setBoostModeDurationInputDescription", type = "java.lang.Long", required = true) @Nullable Long duration) {
- AVMFritzHeatingActionsHandler actionsHandler = handler;
- if (actionsHandler == null) {
- throw new IllegalArgumentException("AVMFritzHeatingActions ThingHandler is null!");
- }
- if (duration == null) {
- throw new IllegalArgumentException("Cannot set Boost mode as 'duration' is null!");
- }
- actionsHandler.setBoostMode(duration.longValue());
- }
-
- public static void setBoostMode(@Nullable ThingActions actions, @Nullable Long duration) {
- invokeMethodOf(actions).setBoostMode(duration);
- }
-
- @Override
- @RuleAction(label = "@text/setWindowOpenModeActionLabel", description = "@text/setWindowOpenModeActionDescription")
- public void setWindowOpenMode(
- @ActionInput(name = "Duration", label = "@text/setWindowOpenModeDurationInputLabel", description = "@text/setWindowOpenModeDurationInputDescription", type = "java.lang.Long", required = true) @Nullable Long duration) {
- AVMFritzHeatingActionsHandler actionsHandler = handler;
- if (actionsHandler == null) {
- throw new IllegalArgumentException("AVMFritzHeatingActions ThingHandler is null!");
- }
- if (duration == null) {
- throw new IllegalArgumentException("Cannot set Window Open mode as 'duration' is null!");
- }
- actionsHandler.setWindowOpenMode(duration.longValue());
- }
-
- public static void setWindowOpenMode(@Nullable ThingActions actions, @Nullable Long duration) {
- invokeMethodOf(actions).setWindowOpenMode(duration);
- }
-
- private static IAVMFritzHeatingActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(AVMFritzHeatingActions.class.getName())) {
- if (actions instanceof IAVMFritzHeatingActions) {
- return (IAVMFritzHeatingActions) actions;
- } else {
- return (IAVMFritzHeatingActions) Proxy.newProxyInstance(IAVMFritzHeatingActions.class.getClassLoader(),
- new Class[] { IAVMFritzHeatingActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of AVMFritzHeatingActions");
- }
-}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.avmfritz.internal.actions;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.avmfritz.internal.handler.AVMFritzHeatingActionsHandler;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+
+/**
+ * The {@link AVMFritzHeatingActions} defines thing actions for heating devices / groups of the avmfritz binding.
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+@ThingActionsScope(name = "avmfritz")
+@NonNullByDefault
+public class AVMFritzHeatingActions implements ThingActions {
+
+ private @Nullable AVMFritzHeatingActionsHandler handler;
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ this.handler = (AVMFritzHeatingActionsHandler) handler;
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+
+ @RuleAction(label = "@text/setBoostModeModeActionLabel", description = "@text/setBoostModeActionDescription")
+ public void setBoostMode(
+ @ActionInput(name = "Duration", label = "@text/setBoostModeDurationInputLabel", description = "@text/setBoostModeDurationInputDescription", type = "java.lang.Long", required = true) @Nullable Long duration) {
+ AVMFritzHeatingActionsHandler actionsHandler = handler;
+ if (actionsHandler == null) {
+ throw new IllegalArgumentException("AVMFritzHeatingActions ThingHandler is null!");
+ }
+ if (duration == null) {
+ throw new IllegalArgumentException("Cannot set Boost mode as 'duration' is null!");
+ }
+ actionsHandler.setBoostMode(duration.longValue());
+ }
+
+ public static void setBoostMode(@Nullable ThingActions actions, @Nullable Long duration) {
+ if (actions instanceof AVMFritzHeatingActions) {
+ ((AVMFritzHeatingActions) actions).setBoostMode(duration);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of AVMFritzHeatingActions");
+ }
+ }
+
+ @RuleAction(label = "@text/setWindowOpenModeActionLabel", description = "@text/setWindowOpenModeActionDescription")
+ public void setWindowOpenMode(
+ @ActionInput(name = "Duration", label = "@text/setWindowOpenModeDurationInputLabel", description = "@text/setWindowOpenModeDurationInputDescription", type = "java.lang.Long", required = true) @Nullable Long duration) {
+ AVMFritzHeatingActionsHandler actionsHandler = handler;
+ if (actionsHandler == null) {
+ throw new IllegalArgumentException("AVMFritzHeatingActions ThingHandler is null!");
+ }
+ if (duration == null) {
+ throw new IllegalArgumentException("Cannot set Window Open mode as 'duration' is null!");
+ }
+ actionsHandler.setWindowOpenMode(duration.longValue());
+ }
+
+ public static void setWindowOpenMode(@Nullable ThingActions actions, @Nullable Long duration) {
+ if (actions instanceof AVMFritzHeatingActions) {
+ ((AVMFritzHeatingActions) actions).setWindowOpenMode(duration);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of AVMFritzHeatingActions");
+ }
+ }
+}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.avmfritz.internal.actions;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.avmfritz.actions.AVMFritzHeatingActions;
-
-/**
- * The {@link IAVMFritzHeatingActions} defines the interface for all thing actions supported by the binding.
- * These methods, parameters, and return types are explained in {@link AVMFritzHeatingActions}.
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-@NonNullByDefault
-public interface IAVMFritzHeatingActions {
-
- void setBoostMode(@Nullable Long duration);
-
- void setWindowOpenMode(@Nullable Long duration);
-}
import java.util.Collections;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.avmfritz.actions.AVMFritzHeatingActions;
+import org.openhab.binding.avmfritz.internal.actions.AVMFritzHeatingActions;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerService;
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.avmfritz.actions;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.openhab.binding.avmfritz.internal.handler.AVMFritzHeatingActionsHandler;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingHandler;
-
-/**
- * Unit tests for {@link AVMFritzHeatingActions}.
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-@ExtendWith(MockitoExtension.class)
-public class AVMFritzHeatingActionsTest {
-
- private final ThingActions thingActionsStub = new ThingActions() {
- @Override
- public void setThingHandler(ThingHandler handler) {
- }
-
- @Override
- public ThingHandler getThingHandler() {
- return null;
- }
- };
-
- private @Mock AVMFritzHeatingActionsHandler heatingActionsHandler;
-
- private AVMFritzHeatingActions heatingActions;
-
- @BeforeEach
- public void setUp() {
- heatingActions = new AVMFritzHeatingActions();
- }
-
- @Test
- public void testSetBoostModeThingActionsIsNull() {
- assertThrows(IllegalArgumentException.class, () -> AVMFritzHeatingActions.setBoostMode(null, Long.valueOf(5L)));
- }
-
- @Test
- public void testSetBoostModeThingActionsIsNotPushoverThingActions() {
- assertThrows(IllegalArgumentException.class,
- () -> AVMFritzHeatingActions.setBoostMode(thingActionsStub, Long.valueOf(5L)));
- }
-
- @Test
- public void testSetBoostModeThingHandlerIsNull() {
- assertThrows(IllegalArgumentException.class,
- () -> AVMFritzHeatingActions.setBoostMode(heatingActions, Long.valueOf(5L)));
- }
-
- @Test
- public void testSetBoostModeDurationNull() {
- heatingActions.setThingHandler(heatingActionsHandler);
- assertThrows(IllegalArgumentException.class, () -> AVMFritzHeatingActions.setBoostMode(heatingActions, null));
- }
-
- @Test
- public void testSetBoostMode() {
- heatingActions.setThingHandler(heatingActionsHandler);
- AVMFritzHeatingActions.setBoostMode(heatingActions, Long.valueOf(5L));
- }
-
- @Test
- public void testSetWindowOpenModeThingActionsIsNull() {
- assertThrows(IllegalArgumentException.class,
- () -> AVMFritzHeatingActions.setWindowOpenMode(null, Long.valueOf(5L)));
- }
-
- @Test
- public void testSetWindowOpenModeThingActionsIsNotPushoverThingActions() {
- assertThrows(IllegalArgumentException.class,
- () -> AVMFritzHeatingActions.setWindowOpenMode(thingActionsStub, Long.valueOf(5L)));
- }
-
- @Test
- public void testSetWindowOpenModeThingHandlerIsNull() {
- assertThrows(IllegalArgumentException.class,
- () -> AVMFritzHeatingActions.setWindowOpenMode(heatingActions, Long.valueOf(5L)));
- }
-
- @Test
- public void testSetWindowOpenModeDurationNull() {
- heatingActions.setThingHandler(heatingActionsHandler);
- assertThrows(IllegalArgumentException.class,
- () -> AVMFritzHeatingActions.setWindowOpenMode(heatingActions, null));
- }
-
- @Test
- public void testSetWindowOpenMode() {
- heatingActions.setThingHandler(heatingActionsHandler);
- AVMFritzHeatingActions.setWindowOpenMode(heatingActions, Long.valueOf(5L));
- }
-}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.avmfritz.internal.actions;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.openhab.binding.avmfritz.internal.handler.AVMFritzHeatingActionsHandler;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingHandler;
+
+/**
+ * Unit tests for {@link AVMFritzHeatingActions}.
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+@ExtendWith(MockitoExtension.class)
+public class AVMFritzHeatingActionsTest {
+
+ private final ThingActions thingActionsStub = new ThingActions() {
+ @Override
+ public void setThingHandler(ThingHandler handler) {
+ }
+
+ @Override
+ public ThingHandler getThingHandler() {
+ return null;
+ }
+ };
+
+ private @Mock AVMFritzHeatingActionsHandler heatingActionsHandler;
+
+ private AVMFritzHeatingActions heatingActions;
+
+ @BeforeEach
+ public void setUp() {
+ heatingActions = new AVMFritzHeatingActions();
+ }
+
+ @Test
+ public void testSetBoostModeThingActionsIsNull() {
+ assertThrows(IllegalArgumentException.class, () -> AVMFritzHeatingActions.setBoostMode(null, Long.valueOf(5L)));
+ }
+
+ @Test
+ public void testSetBoostModeThingActionsIsNotPushoverThingActions() {
+ assertThrows(IllegalArgumentException.class,
+ () -> AVMFritzHeatingActions.setBoostMode(thingActionsStub, Long.valueOf(5L)));
+ }
+
+ @Test
+ public void testSetBoostModeThingHandlerIsNull() {
+ assertThrows(IllegalArgumentException.class,
+ () -> AVMFritzHeatingActions.setBoostMode(heatingActions, Long.valueOf(5L)));
+ }
+
+ @Test
+ public void testSetBoostModeDurationNull() {
+ heatingActions.setThingHandler(heatingActionsHandler);
+ assertThrows(IllegalArgumentException.class, () -> AVMFritzHeatingActions.setBoostMode(heatingActions, null));
+ }
+
+ @Test
+ public void testSetBoostMode() {
+ heatingActions.setThingHandler(heatingActionsHandler);
+ AVMFritzHeatingActions.setBoostMode(heatingActions, Long.valueOf(5L));
+ }
+
+ @Test
+ public void testSetWindowOpenModeThingActionsIsNull() {
+ assertThrows(IllegalArgumentException.class,
+ () -> AVMFritzHeatingActions.setWindowOpenMode(null, Long.valueOf(5L)));
+ }
+
+ @Test
+ public void testSetWindowOpenModeThingActionsIsNotPushoverThingActions() {
+ assertThrows(IllegalArgumentException.class,
+ () -> AVMFritzHeatingActions.setWindowOpenMode(thingActionsStub, Long.valueOf(5L)));
+ }
+
+ @Test
+ public void testSetWindowOpenModeThingHandlerIsNull() {
+ assertThrows(IllegalArgumentException.class,
+ () -> AVMFritzHeatingActions.setWindowOpenMode(heatingActions, Long.valueOf(5L)));
+ }
+
+ @Test
+ public void testSetWindowOpenModeDurationNull() {
+ heatingActions.setThingHandler(heatingActionsHandler);
+ assertThrows(IllegalArgumentException.class,
+ () -> AVMFritzHeatingActions.setWindowOpenMode(heatingActions, null));
+ }
+
+ @Test
+ public void testSetWindowOpenMode() {
+ heatingActions.setThingHandler(heatingActionsHandler);
+ AVMFritzHeatingActions.setWindowOpenMode(heatingActions, Long.valueOf(5L));
+ }
+}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.dmx.action;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.dmx.internal.DmxBridgeHandler;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link DmxActions} provides actions for DMX Bridges
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof DmxActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link DmxActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
- *
- * @author Jan N. Klug - Initial contribution
- */
-
-@ThingActionsScope(name = "dmx")
-@NonNullByDefault
-public class DmxActions implements ThingActions, IDmxActions {
-
- private final Logger logger = LoggerFactory.getLogger(DmxActions.class);
-
- private @Nullable DmxBridgeHandler handler;
-
- @Override
- @RuleAction(label = "DMX Output", description = "immediately performs fade on selected DMX channels")
- public void sendFade(@ActionInput(name = "channels") @Nullable String channels,
- @ActionInput(name = "fade") @Nullable String fade,
- @ActionInput(name = "resumeAfter") @Nullable Boolean resumeAfter) {
- logger.debug("thingHandlerAction called with inputs: {} {} {}", channels, fade, resumeAfter);
-
- if (handler == null) {
- logger.warn("DMX Action service ThingHandler is null!");
- return;
- }
-
- if (channels == null) {
- logger.debug("skipping immediate DMX action {} due to missing channel(s)", fade);
- return;
- }
-
- if (fade == null) {
- logger.debug("skipping immediate DMX action channel(s) {} due to missing fade", channels);
- return;
- }
-
- if (resumeAfter == null) {
- logger.debug("DMX action {} to channel(s) {} with default resumeAfter=false", fade, channels);
- handler.immediateFade(channels, fade, false);
- } else {
- handler.immediateFade(channels, fade, resumeAfter);
- }
- }
-
- public static void sendFade(@Nullable ThingActions actions, @Nullable String channels, @Nullable String fade,
- @Nullable Boolean resumeAfter) {
- invokeMethodOf(actions).sendFade(channels, fade, resumeAfter);
- }
-
- private static IDmxActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(DmxActions.class.getName())) {
- if (actions instanceof IDmxActions) {
- return (IDmxActions) actions;
- } else {
- return (IDmxActions) Proxy.newProxyInstance(IDmxActions.class.getClassLoader(),
- new Class[] { IDmxActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of DmxActions");
- }
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- if (handler instanceof DmxBridgeHandler) {
- this.handler = (DmxBridgeHandler) handler;
- }
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.dmx.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link IDmxActions} defines the actions for DMX Bridges
- *
- * @author Laurent Garnier - Initial contribution
- */
-@NonNullByDefault
-public interface IDmxActions {
-
- public void sendFade(@Nullable String channels, @Nullable String fade, @Nullable Boolean resumeAfter);
-}
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-import org.openhab.binding.dmx.action.DmxActions;
+import org.openhab.binding.dmx.internal.action.DmxActions;
import org.openhab.binding.dmx.internal.action.FadeAction;
import org.openhab.binding.dmx.internal.action.ResumeAction;
import org.openhab.binding.dmx.internal.config.DmxBridgeHandlerConfiguration;
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dmx.internal.action;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.dmx.internal.DmxBridgeHandler;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link DmxActions} provides actions for DMX Bridges
+ *
+ * @author Jan N. Klug - Initial contribution
+ */
+@ThingActionsScope(name = "dmx")
+@NonNullByDefault
+public class DmxActions implements ThingActions {
+
+ private final Logger logger = LoggerFactory.getLogger(DmxActions.class);
+
+ private @Nullable DmxBridgeHandler handler;
+
+ @RuleAction(label = "immediately fade channels", description = "Immediately performs fade on selected DMX channels.")
+ public void sendFade(@ActionInput(name = "channels") @Nullable String channels,
+ @ActionInput(name = "fade") @Nullable String fade,
+ @ActionInput(name = "resumeAfter") @Nullable Boolean resumeAfter) {
+ logger.debug("thingHandlerAction called with inputs: {} {} {}", channels, fade, resumeAfter);
+ DmxBridgeHandler handler = this.handler;
+
+ if (handler == null) {
+ logger.warn("DMX Action service ThingHandler is null!");
+ return;
+ }
+
+ if (channels == null) {
+ logger.debug("skipping immediate DMX action {} due to missing channel(s)", fade);
+ return;
+ }
+
+ if (fade == null) {
+ logger.debug("skipping immediate DMX action channel(s) {} due to missing fade", channels);
+ return;
+ }
+
+ if (resumeAfter == null) {
+ logger.debug("DMX action {} to channel(s) {} with default resumeAfter=false", fade, channels);
+ handler.immediateFade(channels, fade, false);
+ } else {
+ handler.immediateFade(channels, fade, resumeAfter);
+ }
+ }
+
+ public static void sendFade(@Nullable ThingActions actions, @Nullable String channels, @Nullable String fade,
+ @Nullable Boolean resumeAfter) {
+ if (actions instanceof DmxActions) {
+ ((DmxActions) actions).sendFade(channels, fade, resumeAfter);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of DmxActions");
+ }
+ }
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ if (handler instanceof DmxBridgeHandler) {
+ this.handler = (DmxBridgeHandler) handler;
+ }
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.doorbird.action;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.doorbird.internal.handler.DoorbellHandler;
-import org.openhab.core.automation.annotation.ActionOutput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link DoorbirdActions} defines rule actions for the doorbird binding.
- *
- * @author Mark Hilbush - Initial contribution
- */
-@ThingActionsScope(name = "doorbird")
-@NonNullByDefault
-public class DoorbirdActions implements ThingActions {
- private static final Logger LOGGER = LoggerFactory.getLogger(DoorbirdActions.class);
-
- private @Nullable DoorbellHandler handler;
-
- public DoorbirdActions() {
- LOGGER.debug("DoorbirdActions service created");
- }
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- if (handler instanceof DoorbellHandler) {
- this.handler = (DoorbellHandler) handler;
- }
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- private static IDoorbirdActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(DoorbirdActions.class.getName())) {
- if (actions instanceof IDoorbirdActions) {
- return (IDoorbirdActions) actions;
- } else {
- return (IDoorbirdActions) Proxy.newProxyInstance(IDoorbirdActions.class.getClassLoader(),
- new Class[] { IDoorbirdActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("actions is not an instance of DoorbirdActions");
- }
-
- @RuleAction(label = "Restart Doorbird", description = "Restarts the Doorbird device")
- public void restart() {
- LOGGER.debug("Doorbird action 'restart' called");
- if (handler != null) {
- handler.actionRestart();
- } else {
- LOGGER.info("Doorbird Action service ThingHandler is null!");
- }
- }
-
- public static void restart(@Nullable ThingActions actions) {
- invokeMethodOf(actions).restart();
- }
-
- @RuleAction(label = "SIP Hangup", description = "Hangup SIP call")
- public void sipHangup() {
- LOGGER.debug("Doorbird action 'sipHangup' called");
- if (handler != null) {
- handler.actionSIPHangup();
- } else {
- LOGGER.info("Doorbird Action service ThingHandler is null!");
- }
- }
-
- public static void sipHangup(@Nullable ThingActions actions) {
- invokeMethodOf(actions).sipHangup();
- }
-
- @RuleAction(label = "Get Ring Time Limit", description = "Get the value of RING_TIME_LIMIT")
- public @ActionOutput(name = "getRingTimeLimit", type = "java.lang.String") String getRingTimeLimit() {
- LOGGER.debug("Doorbird action 'getRingTimeLimit' called");
- if (handler != null) {
- return handler.actionGetRingTimeLimit();
- } else {
- LOGGER.info("Doorbird Action service ThingHandler is null!");
- return "";
- }
- }
-
- public static String getRingTimeLimit(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).getRingTimeLimit();
- }
-
- @RuleAction(label = "Get Call Time Limit", description = "Get the value of CALL_TIME_LIMIT")
- public @ActionOutput(name = "getCallTimeLimit", type = "java.lang.String") String getCallTimeLimit() {
- LOGGER.debug("Doorbird action 'getCallTimeLimit' called");
- if (handler != null) {
- return handler.actionGetCallTimeLimit();
- } else {
- LOGGER.info("Doorbird Action service ThingHandler is null!");
- return "";
- }
- }
-
- public static String getCallTimeLimit(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).getCallTimeLimit();
- }
-
- @RuleAction(label = "Get Last Error Code", description = "Get the value of LASTERRORCODE")
- public @ActionOutput(name = "getLastErrorCode", type = "java.lang.String") String getLastErrorCode() {
- LOGGER.debug("Doorbird action 'getLastErrorCode' called");
- if (handler != null) {
- return handler.actionGetLastErrorCode();
- } else {
- LOGGER.info("Doorbird Action service ThingHandler is null!");
- return "";
- }
- }
-
- public static String getLastErrorCode(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).getLastErrorCode();
- }
-
- @RuleAction(label = "Get Last Error Text", description = "Get the value of LASTERRORTEXT")
- public @ActionOutput(name = "getLastErrorText", type = "java.lang.String") String getLastErrorText() {
- LOGGER.debug("Doorbird action 'getLastErrorText' called");
- if (handler != null) {
- return handler.actionGetLastErrorText();
- } else {
- LOGGER.info("Doorbird Action service ThingHandler is null!");
- return "";
- }
- }
-
- public static String getLastErrorText(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).getLastErrorText();
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.doorbird.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * The {@link IDoorbirdActions} defines the interface for all thing actions supported by the binding.
- * These methods, parameters, and return types are explained in {@link DoorbirdActions}.
- *
- * @author Mark Hilbush - Initial contribution
- */
-@NonNullByDefault
-public interface IDoorbirdActions {
-
- public void restart();
-
- public void sipHangup();
-
- public String getRingTimeLimit();
-
- public String getCallTimeLimit();
-
- public String getLastErrorCode();
-
- public String getLastErrorText();
-}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.doorbird.internal.action;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.doorbird.internal.handler.DoorbellHandler;
+import org.openhab.core.automation.annotation.ActionOutput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link DoorbirdActions} defines rule actions for the doorbird binding.
+ *
+ * @author Mark Hilbush - Initial contribution
+ */
+@ThingActionsScope(name = "doorbird")
+@NonNullByDefault
+public class DoorbirdActions implements ThingActions {
+ private final Logger logger = LoggerFactory.getLogger(DoorbirdActions.class);
+
+ private @Nullable DoorbellHandler handler;
+
+ public DoorbirdActions() {
+ logger.debug("DoorbirdActions service created");
+ }
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ if (handler instanceof DoorbellHandler) {
+ this.handler = (DoorbellHandler) handler;
+ }
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+
+ @RuleAction(label = "restart the Doorbird", description = "Restarts the Doorbird device.")
+ public void restart() {
+ logger.debug("Doorbird action 'restart' called");
+ if (handler != null) {
+ handler.actionRestart();
+ } else {
+ logger.info("Doorbird Action service ThingHandler is null!");
+ }
+ }
+
+ public static void restart(@Nullable ThingActions actions) {
+ if (actions instanceof DoorbirdActions) {
+ ((DoorbirdActions) actions).restart();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of DoorbirdActions");
+ }
+ }
+
+ @RuleAction(label = "hangup a SIP call", description = "Hangup SIP call.")
+ public void sipHangup() {
+ logger.debug("Doorbird action 'sipHangup' called");
+ if (handler != null) {
+ handler.actionSIPHangup();
+ } else {
+ logger.info("Doorbird Action service ThingHandler is null!");
+ }
+ }
+
+ public static void sipHangup(@Nullable ThingActions actions) {
+ if (actions instanceof DoorbirdActions) {
+ ((DoorbirdActions) actions).sipHangup();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of DoorbirdActions");
+ }
+ }
+
+ @RuleAction(label = "get the ring time limit", description = "Get the value of RING_TIME_LIMIT.")
+ public @ActionOutput(name = "getRingTimeLimit", type = "java.lang.String") String getRingTimeLimit() {
+ logger.debug("Doorbird action 'getRingTimeLimit' called");
+ if (handler != null) {
+ return handler.actionGetRingTimeLimit();
+ } else {
+ logger.info("Doorbird Action service ThingHandler is null!");
+ return "";
+ }
+ }
+
+ public static String getRingTimeLimit(@Nullable ThingActions actions) {
+ if (actions instanceof DoorbirdActions) {
+ return ((DoorbirdActions) actions).getRingTimeLimit();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of DoorbirdActions");
+ }
+ }
+
+ @RuleAction(label = "get the call time limit", description = "Get the value of CALL_TIME_LIMIT.")
+ public @ActionOutput(name = "getCallTimeLimit", type = "java.lang.String") String getCallTimeLimit() {
+ logger.debug("Doorbird action 'getCallTimeLimit' called");
+ if (handler != null) {
+ return handler.actionGetCallTimeLimit();
+ } else {
+ logger.info("Doorbird Action service ThingHandler is null!");
+ return "";
+ }
+ }
+
+ public static String getCallTimeLimit(@Nullable ThingActions actions) {
+ if (actions instanceof DoorbirdActions) {
+ return ((DoorbirdActions) actions).getCallTimeLimit();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of DoorbirdActions");
+ }
+ }
+
+ @RuleAction(label = "get the last error code", description = "Get the value of LASTERRORCODE.")
+ public @ActionOutput(name = "getLastErrorCode", type = "java.lang.String") String getLastErrorCode() {
+ logger.debug("Doorbird action 'getLastErrorCode' called");
+ if (handler != null) {
+ return handler.actionGetLastErrorCode();
+ } else {
+ logger.info("Doorbird Action service ThingHandler is null!");
+ return "";
+ }
+ }
+
+ public static String getLastErrorCode(@Nullable ThingActions actions) {
+ if (actions instanceof DoorbirdActions) {
+ return ((DoorbirdActions) actions).getLastErrorCode();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of DoorbirdActions");
+ }
+ }
+
+ @RuleAction(label = "get the last error text", description = "Get the value of LASTERRORTEXT.")
+ public @ActionOutput(name = "getLastErrorText", type = "java.lang.String") String getLastErrorText() {
+ logger.debug("Doorbird action 'getLastErrorText' called");
+ if (handler != null) {
+ return handler.actionGetLastErrorText();
+ } else {
+ logger.info("Doorbird Action service ThingHandler is null!");
+ return "";
+ }
+ }
+
+ public static String getLastErrorText(@Nullable ThingActions actions) {
+ if (actions instanceof DoorbirdActions) {
+ return ((DoorbirdActions) actions).getLastErrorText();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of DoorbirdActions");
+ }
+ }
+}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
-import org.openhab.binding.doorbird.action.DoorbirdActions;
+import org.openhab.binding.doorbird.internal.action.DoorbirdActions;
import org.openhab.binding.doorbird.internal.api.DoorbirdAPI;
import org.openhab.binding.doorbird.internal.api.DoorbirdImage;
import org.openhab.binding.doorbird.internal.api.SipStatus;
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.ecobee.action;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.measure.quantity.Temperature;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.ecobee.internal.dto.thermostat.EventDTO;
-import org.openhab.binding.ecobee.internal.enums.AckType;
-import org.openhab.binding.ecobee.internal.enums.FanMode;
-import org.openhab.binding.ecobee.internal.enums.HoldType;
-import org.openhab.binding.ecobee.internal.enums.PlugState;
-import org.openhab.binding.ecobee.internal.enums.VentilatorMode;
-import org.openhab.binding.ecobee.internal.function.AcknowledgeFunction;
-import org.openhab.binding.ecobee.internal.function.ControlPlugFunction;
-import org.openhab.binding.ecobee.internal.function.CreateVacationFunction;
-import org.openhab.binding.ecobee.internal.function.DeleteVacationFunction;
-import org.openhab.binding.ecobee.internal.function.ResetPreferencesFunction;
-import org.openhab.binding.ecobee.internal.function.ResumeProgramFunction;
-import org.openhab.binding.ecobee.internal.function.SendMessageFunction;
-import org.openhab.binding.ecobee.internal.function.SetHoldFunction;
-import org.openhab.binding.ecobee.internal.function.SetOccupiedFunction;
-import org.openhab.binding.ecobee.internal.function.UpdateSensorFunction;
-import org.openhab.binding.ecobee.internal.handler.EcobeeThermostatBridgeHandler;
-import org.openhab.binding.ecobee.internal.handler.EcobeeUtils;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.ActionOutput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link EcobeeActions} defines the thing actions for the Ecobee binding.
- * <p>
- * <b>Note:</b>The static method <b>invokeMethod</b> handles the case where
- * the test <i>actions instanceof EcobeeActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link EcobeeActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
- *
- * @author John Cocula - Initial contribution
- * @author Mark Hilbush - Adapted for OH2/3
- * @author Connor Petty - Proxy method for invoking actions
- */
-@ThingActionsScope(name = "ecobee")
-@NonNullByDefault
-public class EcobeeActions implements ThingActions, IEcobeeActions {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(EcobeeActions.class);
-
- private @Nullable EcobeeThermostatBridgeHandler handler;
-
- public EcobeeActions() {
- LOGGER.debug("EcobeeActions: EcobeeActions: Actions service created");
- }
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- if (handler instanceof EcobeeThermostatBridgeHandler) {
- this.handler = (EcobeeThermostatBridgeHandler) handler;
- }
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- private static IEcobeeActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(EcobeeActions.class.getName())) {
- if (actions instanceof IEcobeeActions) {
- return (IEcobeeActions) actions;
- } else {
- return (IEcobeeActions) Proxy.newProxyInstance(IEcobeeActions.class.getClassLoader(),
- new Class[] { IEcobeeActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
- }
-
- /**
- * The acknowledge function allows an alert to be acknowledged.
- *
- * @see <a
- * href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/Acknowledge.shtml">Acknowledge
- * </a>
- */
- @Override
- @RuleAction(label = "Acknowledge", description = "Acknowledges an alert.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean acknowledge(
- @ActionInput(name = "ackRef", description = "The acknowledge ref of alert") @Nullable String ackRef,
- @ActionInput(name = "ackType", description = "The type of acknowledgement. Valid values: accept, decline, defer, unacknowledged") @Nullable String ackType,
- @ActionInput(name = "remindMeLater", description = "(opt) Whether to remind at a later date, if this is a defer acknowledgement") @Nullable Boolean remindMeLater) {
- LOGGER.debug("EcobeeActions: Action 'Acknowledge' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- AcknowledgeFunction function = new AcknowledgeFunction(localHandler.getThermostatId(), ackRef,
- AckType.forValue(ackType), remindMeLater);
- return localHandler.actionPerformFunction(function);
- }
-
- public static boolean acknowledge(@Nullable ThingActions actions, @Nullable String ackRef, @Nullable String ackType,
- @Nullable Boolean remindMeLater) {
- return invokeMethodOf(actions).acknowledge(ackRef, ackType, remindMeLater);
- }
-
- /**
- * Control the on/off state of a plug by setting a hold on the plug.
- *
- * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/ControlPlug.shtml">Control
- * Plug</a>
- */
- @Override
- @RuleAction(label = "Control Plug", description = "Control the on/off state of a plug by setting a hold on the plug.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean controlPlug(
- @ActionInput(name = "plugName", description = "The name of the plug. Ensure each plug has a unique name.") @Nullable String plugName,
- @ActionInput(name = "plugState", description = "The state to put the plug into. Valid values: on, off, resume.") @Nullable String plugState,
- @ActionInput(name = "startDateTime", description = "(opt) The start date/time in thermostat time.") @Nullable Date startDateTime,
- @ActionInput(name = "endDateTime", description = "(opt) The end date/time in thermostat time.") @Nullable Date endDateTime,
- @ActionInput(name = "holdType", description = "(opt) The hold duration type. Valid values: dateTime, nextTransition, indefinite, holdHours.") @Nullable String holdType,
- @ActionInput(name = "holdHours", description = "(opt) The number of hours to hold for, used and required if holdType='holdHours'.") @Nullable Number holdHours) {
- LOGGER.debug("EcobeeActions: Action 'Control Plug' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- ControlPlugFunction function = (new ControlPlugFunction(plugName, PlugState.forValue(plugState), startDateTime,
- endDateTime, (holdType == null) ? null : HoldType.forValue(holdType),
- (holdHours == null) ? null : Integer.valueOf(holdHours.intValue())));
- return localHandler.actionPerformFunction(function);
- }
-
- public static boolean controlPlug(@Nullable ThingActions actions, @Nullable String plugName,
- @Nullable String plugState, @Nullable Date startDateTime, @Nullable Date endDateTime,
- @Nullable String holdType, @Nullable Number holdHours) {
- return invokeMethodOf(actions).controlPlug(plugName, plugState, startDateTime, endDateTime, holdType,
- holdHours);
- }
-
- /**
- * The create vacation function creates a vacation event on the thermostat.
- *
- * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/CreateVacation.shtml">Create
- * Vacation</a>
- */
- @Override
- @RuleAction(label = "Create Vacation", description = "The create vacation function creates a vacation event on the thermostat.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean createVacation(
- @ActionInput(name = "name", description = "The vacation event name. It must be unique.") @Nullable String name,
- @ActionInput(name = "coolHoldTemp", description = "The temperature at which to set the cool vacation hold.") @Nullable QuantityType<Temperature> coolHoldTemp,
- @ActionInput(name = "heatHoldTemp", description = "The temperature at which to set the heat vacation hold.") @Nullable QuantityType<Temperature> heatHoldTemp,
- @ActionInput(name = "startDateTime", description = "(opt) The start date/time in thermostat time.") @Nullable Date startDateTime,
- @ActionInput(name = "endDateTime", description = "(opt) The end date in thermostat time.") @Nullable Date endDateTime,
- @ActionInput(name = "fan", description = "(opt) The fan mode during the vacation. Values: auto, on Default: auto") @Nullable String fan,
- @ActionInput(name = "fanMinOnTime", description = "(opt) The minimum number of minutes to run the fan each hour. Range: 0-60, Default: 0") @Nullable Number fanMinOnTime) {
- LOGGER.debug("EcobeeActions: Action 'Create Vacation' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- CreateVacationFunction function = new CreateVacationFunction(name, coolHoldTemp, heatHoldTemp, startDateTime,
- endDateTime, (fan == null) ? null : FanMode.forValue(fan),
- (fanMinOnTime == null) ? null : Integer.valueOf(fanMinOnTime.intValue()));
- return localHandler.actionPerformFunction(function);
- }
-
- public static boolean createVacation(@Nullable ThingActions actions, @Nullable String name,
- @Nullable QuantityType<Temperature> coolHoldTemp, @Nullable QuantityType<Temperature> heatHoldTemp,
- @Nullable Date startDateTime, @Nullable Date endDateTime, @Nullable String fan,
- @Nullable Number fanMinOnTime) {
- return invokeMethodOf(actions).createVacation(name, coolHoldTemp, heatHoldTemp, startDateTime, endDateTime, fan,
- fanMinOnTime);
- }
-
- /**
- * The delete vacation function deletes a vacation event from a thermostat.
- *
- * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/DeleteVacation.shtml">Delete
- * Vacation</a>
- */
- @Override
- @RuleAction(label = "Delete Vacation", description = "The delete vacation function deletes a vacation event from a thermostat.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean deleteVacation(
- @ActionInput(name = "name", description = "The vacation event name to delete.") @Nullable String name) {
- LOGGER.debug("EcobeeActions: Action 'Delete Vacation' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- DeleteVacationFunction function = new DeleteVacationFunction(name);
- return localHandler.actionPerformFunction(function);
- }
-
- public static boolean deleteVacation(@Nullable ThingActions actions, @Nullable String name) {
- return invokeMethodOf(actions).deleteVacation(name);
- }
-
- /**
- * The reset preferences function sets all of the user configurable settings back to the factory default values.
- *
- * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/ResetPreferences.shtml">Reset
- * Preferences</a>
- */
- @Override
- @RuleAction(label = "Reset Preferences", description = "The reset preferences function sets all of the user configurable settings back to the factory default values.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean resetPreferences() {
- LOGGER.debug("EcobeeActions: Action 'Reset Preferences' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- ResetPreferencesFunction function = new ResetPreferencesFunction();
- return localHandler.actionPerformFunction(function);
- }
-
- public static boolean resetPreferences(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).resetPreferences();
- }
-
- /**
- * The resume program function removes the currently running event.
- *
- * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/ResumeProgram.shtml">Resume
- * Program</a>
- */
- @Override
- @RuleAction(label = "Resume Program", description = "Removes the currently running event providing the event is not a mandatory demand response event")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean resumeProgram(
- @ActionInput(name = "resumeAll", description = "(opt) Should the thermostat be resumed to next event (false) or to its program (true)") @Nullable Boolean resumeAll) {
- LOGGER.debug("EcobeeActions: Action 'Resume Program' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- ResumeProgramFunction function = new ResumeProgramFunction(resumeAll);
- return localHandler.actionPerformFunction(function);
- }
-
- public static boolean resumeProgram(@Nullable ThingActions actions, @Nullable Boolean resumeAll) {
- return invokeMethodOf(actions).resumeProgram(resumeAll);
- }
-
- /**
- * The send message function allows an alert message to be sent to the thermostat.
- *
- * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/SendMessage.shtml">Send
- * Message</a>
- */
- @Override
- @RuleAction(label = "Send Message", description = "The send message function allows an alert message to be sent to the thermostat.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMessage(
- @ActionInput(name = "text", description = "The message text to send. Text will be truncated to 500 characters if longer") @Nullable String text) {
- LOGGER.debug("EcobeeActions: Action 'SendMessage' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- SendMessageFunction function = new SendMessageFunction(text);
- return localHandler.actionPerformFunction(function);
- }
-
- public static boolean sendMessage(@Nullable ThingActions actions, @Nullable String text) {
- return invokeMethodOf(actions).sendMessage(text);
- }
-
- /**
- * Set an indefinite hold using the supplied the cool and heat hold temperatures
- *
- * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/SetHold.shtml">Set Hold</a>
- */
- @Override
- @RuleAction(label = "Set Hold", description = "The set hold function sets the thermostat into a hold with the specified temperatures.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
- @ActionInput(name = "coolHoldTemp", description = "The temperature at which to set the cool hold.") @Nullable QuantityType<Temperature> coolHoldTemp,
- @ActionInput(name = "heatHoldTemp", description = "The temperature at which to set the heat hold.") @Nullable QuantityType<Temperature> heatHoldTemp) {
- if (coolHoldTemp == null || heatHoldTemp == null) {
- throw new IllegalArgumentException("hold temperatures cannot be null");
- }
- Map<String, Object> params = new HashMap<String, Object>();
- params.put("coolHoldTemp", coolHoldTemp);
- params.put("heatHoldTemp", heatHoldTemp);
- return setHold(params, null, null, null, null);
- }
-
- public static boolean setHold(@Nullable ThingActions actions, @Nullable QuantityType<Temperature> coolHoldTemp,
- @Nullable QuantityType<Temperature> heatHoldTemp) {
- return invokeMethodOf(actions).setHold(coolHoldTemp, heatHoldTemp);
- }
-
- /**
- * Set a hold by providing the cool and heat temperatures and the number of hours.
- */
- @Override
- @RuleAction(label = "Set Hold", description = "The set hold function sets the thermostat into a hold for the specified number of hours.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
- @ActionInput(name = "coolHoldTemp", description = "The temperature at which to set the cool hold.") @Nullable QuantityType<Temperature> coolHoldTemp,
- @ActionInput(name = "heatHoldTemp", description = "The temperature at which to set the heat hold.") @Nullable QuantityType<Temperature> heatHoldTemp,
- @ActionInput(name = "holdHours", description = "The number of hours for the hold.") @Nullable Number holdHours) {
- if (coolHoldTemp == null || heatHoldTemp == null) {
- throw new IllegalArgumentException("hold temperatures cannot be null");
- }
- if (holdHours == null) {
- throw new IllegalArgumentException("number of hold hours is missing");
- }
- Map<String, Object> params = new HashMap<String, Object>();
- params.put("coolHoldTemp", coolHoldTemp);
- params.put("heatHoldTemp", heatHoldTemp);
- params.put("holdType", HoldType.HOLD_HOURS);
- params.put("holdHours", Integer.valueOf(holdHours.intValue()));
- return setHold(params, null, null, null, null);
- }
-
- public static boolean setHold(@Nullable ThingActions actions, @Nullable QuantityType<Temperature> coolHoldTemp,
- @Nullable QuantityType<Temperature> heatHoldTemp, @Nullable Number holdHours) {
- return invokeMethodOf(actions).setHold(coolHoldTemp, heatHoldTemp, holdHours);
- }
-
- /**
- * Set an indefinite hold using the supplied climateRef
- */
- @Override
- @RuleAction(label = "Set Hold", description = "The set hold function sets the thermostat into a hold with the specified climate ref.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
- @ActionInput(name = "holdClimateRef", description = "The holdClimateRef used to set the hold.") @Nullable String holdClimateRef) {
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- if (holdClimateRef == null || !localHandler.isValidClimateRef(holdClimateRef)) {
- throw new IllegalArgumentException("hold climate ref is missing or invalid");
- }
- Map<String, Object> params = new HashMap<String, Object>();
- params.put("holdClimateRef", holdClimateRef);
- return setHold(params, null, null, null, null);
- }
-
- public static boolean setHold(@Nullable ThingActions actions, @Nullable String holdClimateRef) {
- return invokeMethodOf(actions).setHold(holdClimateRef);
- }
-
- /**
- * Set a hold using the supplied climateRef for the supplied number of hours.
- */
- @Override
- @RuleAction(label = "Set Hold", description = "The set hold function sets the thermostat into a hold with the specified climate ref.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
- @ActionInput(name = "holdClimateRef", description = "The holdClimateRef used to set the hold.") @Nullable String holdClimateRef,
- @ActionInput(name = "holdHours", description = "The number of hours for the hold.") @Nullable Number holdHours) {
- if (holdHours == null) {
- throw new IllegalArgumentException("number of hold hours is missing");
- }
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- if (holdClimateRef == null || !localHandler.isValidClimateRef(holdClimateRef)) {
- throw new IllegalArgumentException("hold climate ref is missing or invalid");
- }
- Map<String, Object> params = new HashMap<String, Object>();
- params.put("holdClimateRef", holdClimateRef);
- params.put("holdType", HoldType.HOLD_HOURS);
- params.put("holdHours", Integer.valueOf(holdHours.intValue()));
- return setHold(params, null, null, null, null);
- }
-
- public static boolean setHold(@Nullable ThingActions actions, @Nullable String holdClimateRef,
- @Nullable Number holdHours) {
- return invokeMethodOf(actions).setHold(holdClimateRef, holdHours);
- }
-
- /**
- * Set a hold
- */
- @Override
- @RuleAction(label = "Set Hold", description = "The set hold function sets the thermostat into a hold with the specified temperature or climate ref.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
- @ActionInput(name = "coolHoldTemp", description = "(opt) The temperature at which to set the cool hold.") @Nullable QuantityType<Temperature> coolHoldTemp,
- @ActionInput(name = "heatHoldTemp", description = "(opt) The temperature at which to set the heat hold.") @Nullable QuantityType<Temperature> heatHoldTemp,
- @ActionInput(name = "holdClimateRef", description = "(opt) The Climate to use as reference for setting the coolHoldTemp, heatHoldTemp and fan settings for this hold. If this value is passed the coolHoldTemp and heatHoldTemp are not required.") @Nullable String holdClimateRef,
- @ActionInput(name = "startDateTime", description = "(opt) The start date in thermostat time.") @Nullable Date startDateTime,
- @ActionInput(name = "endDateTime", description = "(opt) The end date in thermostat time.") @Nullable Date endDateTime,
- @ActionInput(name = "holdType", description = "(opt) The hold duration type. Valid values: dateTime, nextTransition, indefinite, holdHours.") @Nullable String holdType,
- @ActionInput(name = "holdHours", description = "(opt) The number of hours to hold for, used and required if holdType='holdHours'.") @Nullable Number holdHours) {
- Map<String, Object> params = new HashMap<String, Object>();
- if (coolHoldTemp != null) {
- params.put("coolHoldTemp", coolHoldTemp);
- }
- if (heatHoldTemp != null) {
- params.put("heatHoldTemp", heatHoldTemp);
- }
- if (holdClimateRef != null) {
- params.put("holdClimateRef", holdClimateRef);
- }
- return setHold(params, holdType, holdHours, startDateTime, endDateTime);
- }
-
- public static boolean setHold(@Nullable ThingActions actions, @Nullable QuantityType<Temperature> coolHoldTemp,
- @Nullable QuantityType<Temperature> heatHoldTemp, @Nullable String holdClimateRef,
- @Nullable Date startDateTime, @Nullable Date endDateTime, @Nullable String holdType,
- @Nullable Number holdHours) {
- return invokeMethodOf(actions).setHold(coolHoldTemp, heatHoldTemp, holdClimateRef, startDateTime, endDateTime,
- holdType, holdHours);
- }
-
- /**
- * Set a hold by providing a parameter map
- */
- @Override
- @RuleAction(label = "Set Hold", description = "The set hold function sets the thermostat into a hold with the specified event parameters.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
- @ActionInput(name = "params", description = "The map of hold parameters.") @Nullable Map<String, Object> params,
- @ActionInput(name = "holdType", description = "(opt) The hold duration type. Valid values: dateTime, nextTransition, indefinite, holdHours.") @Nullable String holdType,
- @ActionInput(name = "holdHours", description = "(opt) The number of hours to hold for, used and required if holdType='holdHours'.") @Nullable Number holdHours,
- @ActionInput(name = "startDateTime", description = "(opt) The start date in thermostat time.") @Nullable Date startDateTime,
- @ActionInput(name = "endDateTime", description = "(opt) The end date in thermostat time.") @Nullable Date endDateTime) {
- LOGGER.debug("EcobeeActions: Action 'SetHold' called");
- if (params == null) {
- throw new IllegalArgumentException("params cannot be null");
- }
- EventDTO event = new EventDTO();
- for (String key : params.keySet()) {
- Object value = params.get(key);
- switch (key) {
- case "isOccupied":
- event.isOccupied = ((Boolean) value);
- break;
- case "isCoolOff":
- event.isCoolOff = ((Boolean) value);
- break;
- case "isHeatOff":
- event.isHeatOff = ((Boolean) value);
- break;
- case "coolHoldTemp":
- event.coolHoldTemp = EcobeeUtils.convertQuantityTypeToEcobeeTemp(value);
- break;
- case "heatHoldTemp":
- event.heatHoldTemp = EcobeeUtils.convertQuantityTypeToEcobeeTemp(value);
- break;
- case "fan":
- event.fan = FanMode.forValue((String) value).toString();
- break;
- case "vent":
- event.vent = VentilatorMode.forValue((String) value).toString();
- break;
- case "ventilatorMinOnTime":
- event.ventilatorMinOnTime = ((Integer) value);
- break;
- case "isOptional":
- event.isOptional = ((Boolean) value);
- break;
- case "isTemperatureRelative":
- event.isTemperatureRelative = ((Boolean) value);
- break;
- case "coolRelativeTemp":
- event.coolRelativeTemp = EcobeeUtils.convertQuantityTypeToEcobeeTemp(value);
- break;
- case "heatRelativeTemp":
- event.heatRelativeTemp = EcobeeUtils.convertQuantityTypeToEcobeeTemp(value);
- break;
- case "isTemperatureAbsolute":
- event.isTemperatureAbsolute = ((Boolean) value);
- break;
- case "fanMinOnTime":
- event.fanMinOnTime = ((Integer) value);
- break;
- case "holdClimateRef":
- event.holdClimateRef = ((String) value);
- break;
- default:
- LOGGER.warn("Unrecognized event field '{}' with value '{}' ignored.", key, value);
- break;
- }
- }
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- SetHoldFunction function = new SetHoldFunction(event, (holdType == null) ? null : HoldType.forValue(holdType),
- (holdHours == null) ? null : holdHours.intValue(), startDateTime, endDateTime);
- return localHandler.actionPerformFunction(function);
- }
-
- public static boolean setHold(@Nullable ThingActions actions, @Nullable Map<String, Object> params,
- @Nullable String holdType, @Nullable Number holdHours, @Nullable Date startDateTime,
- @Nullable Date endDateTime) {
- return invokeMethodOf(actions).setHold(params, holdType, holdHours, startDateTime, endDateTime);
- }
-
- /**
- * The set occupied function may only be used by EMS thermostats. The function switches a thermostat from occupied
- * mode to unoccupied, or vice versa.
- *
- * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/SetOccupied.shtml">Set
- * Occupied</a>
- */
- @Override
- @RuleAction(label = "Set Occupied", description = "The function switches a thermostat from occupied mode to unoccupied, or vice versa (EMS MODELS ONLY).")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setOccupied(
- @ActionInput(name = "occupied", description = "The climate to use for the temperature, occupied (true) or unoccupied (false).") @Nullable Boolean occupied,
- @ActionInput(name = "startDateTime", description = "(opt) The start date in thermostat time.") @Nullable Date startDateTime,
- @ActionInput(name = "endDateTime", description = "(opt) The end date in thermostat time.") @Nullable Date endDateTime,
- @ActionInput(name = "holdType", description = "(opt) The hold duration type. Valid values: dateTime, nextTransition, indefinite, holdHours.") @Nullable String holdType,
- @ActionInput(name = "holdHours", description = "(opt) The number of hours to hold for, used and required if holdType='holdHours'.") @Nullable Number holdHours) {
- LOGGER.debug("EcobeeActions: Action 'Set Occupied' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- SetOccupiedFunction function = new SetOccupiedFunction(occupied, startDateTime, endDateTime,
- (holdType == null) ? null : HoldType.forValue(holdType),
- (holdHours == null) ? null : Integer.valueOf(holdHours.intValue()));
- return localHandler.actionPerformFunction(function);
- }
-
- public static boolean setOccupied(@Nullable ThingActions actions, @Nullable Boolean occupied,
- @Nullable Date startDateTime, @Nullable Date endDateTime, @Nullable String holdType,
- @Nullable Number holdHours) {
- return invokeMethodOf(actions).setOccupied(occupied, startDateTime, endDateTime, holdType, holdHours);
- }
-
- /**
- * The update sensor function allows the caller to update the name of an ecobee3 remote sensor.
- *
- * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/UpdateSensor.shtml">Update
- * Sensor</a>
- */
- @Override
- @RuleAction(label = "Update Sensor", description = "The update sensor function allows the caller to update the name of an ecobee3 remote sensor.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean updateSensor(
- @ActionInput(name = "name", description = "The updated name to give the sensor. Has a max length of 32, but shorter is recommended.") @Nullable String name,
- @ActionInput(name = "deviceId", description = "The deviceId for the sensor, typically this indicates the enclosure and corresponds to the ThermostatRemoteSensor.id field. For example: rs:100") @Nullable String deviceId,
- @ActionInput(name = "sensorId", description = "The identifier for the sensor within the enclosure. Corresponds to the RemoteSensorCapability.id. For example: 1") @Nullable String sensorId) {
- LOGGER.debug("EcobeeActions: Action 'UpdateSensor' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return false;
- }
- UpdateSensorFunction function = new UpdateSensorFunction(name, deviceId, sensorId);
- return localHandler.actionPerformFunction(function);
- }
-
- public static boolean updateSensor(@Nullable ThingActions actions, @Nullable String name, @Nullable String deviceId,
- @Nullable String sensorId) {
- return invokeMethodOf(actions).updateSensor(name, deviceId, sensorId);
- }
-
- /**
- * Get the alerts list. Returns a JSON string containing all the alerts.
- */
- @Override
- @RuleAction(label = "Get Alerts", description = "Get the alerts list")
- public @ActionOutput(name = "alerts", type = "java.lang.String") @Nullable String getAlerts() {
- LOGGER.debug("EcobeeActions: Action 'Get Alerts' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return null;
- }
- return localHandler.getAlerts();
- }
-
- public static @Nullable String getAlerts(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).getAlerts();
- }
-
- /**
- * Get the events list. Returns a JSON string contains all events.
- */
- @Override
- @RuleAction(label = "Get Events", description = "Get the events list")
- public @ActionOutput(name = "events", type = "java.lang.String") @Nullable String getEvents() {
- LOGGER.debug("EcobeeActions: Action 'Get Events' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return null;
- }
- return localHandler.getEvents();
- }
-
- public static @Nullable String getEvents(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).getEvents();
- }
-
- /**
- * Get a list of climates. Returns a JSON string contains all climates.
- */
- @Override
- @RuleAction(label = "Get Climates", description = "Get a list of climates")
- public @ActionOutput(name = "climates", type = "java.lang.String") @Nullable String getClimates() {
- LOGGER.debug("EcobeeActions: Action 'Get Climates' called");
- EcobeeThermostatBridgeHandler localHandler = handler;
- if (localHandler == null) {
- LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
- return null;
- }
- return localHandler.getClimates();
- }
-
- public static @Nullable String getClimates(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).getClimates();
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.ecobee.action;
-
-import java.util.Date;
-import java.util.Map;
-
-import javax.measure.quantity.Temperature;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.library.types.QuantityType;
-
-/**
- * The {@link IEcobeeActions} defines the interface for all thing actions supported by the binding.
- * These methods, parameters, and return types are explained in {@link EcobeeActions}.
- *
- * @author Mark Hilbush - Initial contribution
- */
-@NonNullByDefault
-public interface IEcobeeActions {
-
- public Boolean acknowledge(@Nullable String ackRef, @Nullable String ackType, @Nullable Boolean remindMeLater);
-
- public Boolean controlPlug(@Nullable String plugName, @Nullable String plugState, @Nullable Date startDateTime,
- @Nullable Date endDateTime, @Nullable String holdType, @Nullable Number holdHours);
-
- public Boolean sendMessage(@Nullable String text);
-
- public Boolean createVacation(@Nullable String name, @Nullable QuantityType<Temperature> coolHoldTemp,
- @Nullable QuantityType<Temperature> heatHoldTemp, @Nullable Date startDateTime, @Nullable Date endDateTime,
- @Nullable String fan, @Nullable Number fanMinOnTime);
-
- public Boolean deleteVacation(@Nullable String name);
-
- public Boolean resetPreferences();
-
- public Boolean resumeProgram(@Nullable Boolean resumeAll);
-
- public Boolean setHold(@Nullable QuantityType<Temperature> coolHoldTemp,
- @Nullable QuantityType<Temperature> heatHoldTemp);
-
- public Boolean setHold(@Nullable QuantityType<Temperature> coolHoldTemp,
- @Nullable QuantityType<Temperature> heatHoldTemp, @Nullable Number holdHours);
-
- public Boolean setHold(@Nullable String holdClimateRef);
-
- public Boolean setHold(@Nullable String holdClimateRef, @Nullable Number holdHours);
-
- public Boolean setHold(@Nullable QuantityType<Temperature> coolHoldTemp,
- @Nullable QuantityType<Temperature> heatHoldTemp, @Nullable String holdClimateRef,
- @Nullable Date startDateTime, @Nullable Date endDateTime, @Nullable String holdType,
- @Nullable Number holdHours);
-
- public Boolean setHold(@Nullable Map<String, Object> params, @Nullable String holdType, @Nullable Number holdHours,
- @Nullable Date startDateTime, @Nullable Date endDateTime);
-
- public Boolean setOccupied(@Nullable Boolean occupied, @Nullable Date startDateTime, @Nullable Date endDateTime,
- @Nullable String holdType, @Nullable Number holdHours);
-
- public Boolean updateSensor(@Nullable String name, @Nullable String deviceId, @Nullable String sensorId);
-
- public @Nullable String getAlerts();
-
- public @Nullable String getEvents();
-
- public @Nullable String getClimates();
-}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.ecobee.internal.action;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.measure.quantity.Temperature;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.ecobee.internal.dto.thermostat.EventDTO;
+import org.openhab.binding.ecobee.internal.enums.AckType;
+import org.openhab.binding.ecobee.internal.enums.FanMode;
+import org.openhab.binding.ecobee.internal.enums.HoldType;
+import org.openhab.binding.ecobee.internal.enums.PlugState;
+import org.openhab.binding.ecobee.internal.enums.VentilatorMode;
+import org.openhab.binding.ecobee.internal.function.AcknowledgeFunction;
+import org.openhab.binding.ecobee.internal.function.ControlPlugFunction;
+import org.openhab.binding.ecobee.internal.function.CreateVacationFunction;
+import org.openhab.binding.ecobee.internal.function.DeleteVacationFunction;
+import org.openhab.binding.ecobee.internal.function.ResetPreferencesFunction;
+import org.openhab.binding.ecobee.internal.function.ResumeProgramFunction;
+import org.openhab.binding.ecobee.internal.function.SendMessageFunction;
+import org.openhab.binding.ecobee.internal.function.SetHoldFunction;
+import org.openhab.binding.ecobee.internal.function.SetOccupiedFunction;
+import org.openhab.binding.ecobee.internal.function.UpdateSensorFunction;
+import org.openhab.binding.ecobee.internal.handler.EcobeeThermostatBridgeHandler;
+import org.openhab.binding.ecobee.internal.handler.EcobeeUtils;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.ActionOutput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link EcobeeActions} defines the thing actions for the Ecobee binding.
+ *
+ * @author John Cocula - Initial contribution
+ * @author Mark Hilbush - Adapted for OH2/3
+ * @author Connor Petty - Proxy method for invoking actions
+ */
+@ThingActionsScope(name = "ecobee")
+@NonNullByDefault
+public class EcobeeActions implements ThingActions {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(EcobeeActions.class);
+
+ private @Nullable EcobeeThermostatBridgeHandler handler;
+
+ public EcobeeActions() {
+ LOGGER.debug("EcobeeActions: EcobeeActions: Actions service created");
+ }
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ if (handler instanceof EcobeeThermostatBridgeHandler) {
+ this.handler = (EcobeeThermostatBridgeHandler) handler;
+ }
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+
+ /**
+ * The acknowledge function allows an alert to be acknowledged.
+ *
+ * @see <a
+ * href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/Acknowledge.shtml">Acknowledge
+ * </a>
+ */
+ @RuleAction(label = "acknowledge an alert", description = "Acknowledges an alert.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean acknowledge(
+ @ActionInput(name = "ackRef", description = "The acknowledge ref of alert") @Nullable String ackRef,
+ @ActionInput(name = "ackType", description = "The type of acknowledgement. Valid values: accept, decline, defer, unacknowledged") @Nullable String ackType,
+ @ActionInput(name = "remindMeLater", description = "(opt) Whether to remind at a later date, if this is a defer acknowledgement") @Nullable Boolean remindMeLater) {
+ LOGGER.debug("EcobeeActions: Action 'Acknowledge' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ AcknowledgeFunction function = new AcknowledgeFunction(localHandler.getThermostatId(), ackRef,
+ AckType.forValue(ackType), remindMeLater);
+ return localHandler.actionPerformFunction(function);
+ }
+
+ public static boolean acknowledge(@Nullable ThingActions actions, @Nullable String ackRef, @Nullable String ackType,
+ @Nullable Boolean remindMeLater) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).acknowledge(ackRef, ackType, remindMeLater);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * Control the on/off state of a plug by setting a hold on the plug.
+ *
+ * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/ControlPlug.shtml">Control
+ * Plug</a>
+ */
+ @RuleAction(label = "control a plug", description = "Control the on/off state of a plug by setting a hold on the plug.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean controlPlug(
+ @ActionInput(name = "plugName", description = "The name of the plug. Ensure each plug has a unique name.") @Nullable String plugName,
+ @ActionInput(name = "plugState", description = "The state to put the plug into. Valid values: on, off, resume.") @Nullable String plugState,
+ @ActionInput(name = "startDateTime", description = "(opt) The start date/time in thermostat time.") @Nullable Date startDateTime,
+ @ActionInput(name = "endDateTime", description = "(opt) The end date/time in thermostat time.") @Nullable Date endDateTime,
+ @ActionInput(name = "holdType", description = "(opt) The hold duration type. Valid values: dateTime, nextTransition, indefinite, holdHours.") @Nullable String holdType,
+ @ActionInput(name = "holdHours", description = "(opt) The number of hours to hold for, used and required if holdType='holdHours'.") @Nullable Number holdHours) {
+ LOGGER.debug("EcobeeActions: Action 'Control Plug' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ ControlPlugFunction function = (new ControlPlugFunction(plugName, PlugState.forValue(plugState), startDateTime,
+ endDateTime, (holdType == null) ? null : HoldType.forValue(holdType),
+ (holdHours == null) ? null : Integer.valueOf(holdHours.intValue())));
+ return localHandler.actionPerformFunction(function);
+ }
+
+ public static boolean controlPlug(@Nullable ThingActions actions, @Nullable String plugName,
+ @Nullable String plugState, @Nullable Date startDateTime, @Nullable Date endDateTime,
+ @Nullable String holdType, @Nullable Number holdHours) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).controlPlug(plugName, plugState, startDateTime, endDateTime, holdType,
+ holdHours);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * The create vacation function creates a vacation event on the thermostat.
+ *
+ * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/CreateVacation.shtml">Create
+ * Vacation</a>
+ */
+ @RuleAction(label = "create a vacation", description = "The create vacation function creates a vacation event on the thermostat.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean createVacation(
+ @ActionInput(name = "name", description = "The vacation event name. It must be unique.") @Nullable String name,
+ @ActionInput(name = "coolHoldTemp", description = "The temperature at which to set the cool vacation hold.") @Nullable QuantityType<Temperature> coolHoldTemp,
+ @ActionInput(name = "heatHoldTemp", description = "The temperature at which to set the heat vacation hold.") @Nullable QuantityType<Temperature> heatHoldTemp,
+ @ActionInput(name = "startDateTime", description = "(opt) The start date/time in thermostat time.") @Nullable Date startDateTime,
+ @ActionInput(name = "endDateTime", description = "(opt) The end date in thermostat time.") @Nullable Date endDateTime,
+ @ActionInput(name = "fan", description = "(opt) The fan mode during the vacation. Values: auto, on Default: auto") @Nullable String fan,
+ @ActionInput(name = "fanMinOnTime", description = "(opt) The minimum number of minutes to run the fan each hour. Range: 0-60, Default: 0") @Nullable Number fanMinOnTime) {
+ LOGGER.debug("EcobeeActions: Action 'Create Vacation' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ CreateVacationFunction function = new CreateVacationFunction(name, coolHoldTemp, heatHoldTemp, startDateTime,
+ endDateTime, (fan == null) ? null : FanMode.forValue(fan),
+ (fanMinOnTime == null) ? null : Integer.valueOf(fanMinOnTime.intValue()));
+ return localHandler.actionPerformFunction(function);
+ }
+
+ public static boolean createVacation(@Nullable ThingActions actions, @Nullable String name,
+ @Nullable QuantityType<Temperature> coolHoldTemp, @Nullable QuantityType<Temperature> heatHoldTemp,
+ @Nullable Date startDateTime, @Nullable Date endDateTime, @Nullable String fan,
+ @Nullable Number fanMinOnTime) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).createVacation(name, coolHoldTemp, heatHoldTemp, startDateTime,
+ endDateTime, fan, fanMinOnTime);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * The delete vacation function deletes a vacation event from a thermostat.
+ *
+ * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/DeleteVacation.shtml">Delete
+ * Vacation</a>
+ */
+ @RuleAction(label = "delete a vacation", description = "The delete vacation function deletes a vacation event from a thermostat.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean deleteVacation(
+ @ActionInput(name = "name", description = "The vacation event name to delete.") @Nullable String name) {
+ LOGGER.debug("EcobeeActions: Action 'Delete Vacation' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ DeleteVacationFunction function = new DeleteVacationFunction(name);
+ return localHandler.actionPerformFunction(function);
+ }
+
+ public static boolean deleteVacation(@Nullable ThingActions actions, @Nullable String name) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).deleteVacation(name);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * The reset preferences function sets all of the user configurable settings back to the factory default values.
+ *
+ * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/ResetPreferences.shtml">Reset
+ * Preferences</a>
+ */
+ @RuleAction(label = "reset the preferences", description = "The reset preferences function sets all of the user configurable settings back to the factory default values.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean resetPreferences() {
+ LOGGER.debug("EcobeeActions: Action 'Reset Preferences' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ ResetPreferencesFunction function = new ResetPreferencesFunction();
+ return localHandler.actionPerformFunction(function);
+ }
+
+ public static boolean resetPreferences(@Nullable ThingActions actions) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).resetPreferences();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * The resume program function removes the currently running event.
+ *
+ * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/ResumeProgram.shtml">Resume
+ * Program</a>
+ */
+ @RuleAction(label = "resume the program", description = "Removes the currently running event providing the event is not a mandatory demand response event")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean resumeProgram(
+ @ActionInput(name = "resumeAll", description = "(opt) Should the thermostat be resumed to next event (false) or to its program (true)") @Nullable Boolean resumeAll) {
+ LOGGER.debug("EcobeeActions: Action 'Resume Program' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ ResumeProgramFunction function = new ResumeProgramFunction(resumeAll);
+ return localHandler.actionPerformFunction(function);
+ }
+
+ public static boolean resumeProgram(@Nullable ThingActions actions, @Nullable Boolean resumeAll) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).resumeProgram(resumeAll);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * The send message function allows an alert message to be sent to the thermostat.
+ *
+ * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/SendMessage.shtml">Send
+ * Message</a>
+ */
+ @RuleAction(label = "send a message", description = "The send message function allows an alert message to be sent to the thermostat.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMessage(
+ @ActionInput(name = "text", description = "The message text to send. Text will be truncated to 500 characters if longer") @Nullable String text) {
+ LOGGER.debug("EcobeeActions: Action 'SendMessage' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ SendMessageFunction function = new SendMessageFunction(text);
+ return localHandler.actionPerformFunction(function);
+ }
+
+ public static boolean sendMessage(@Nullable ThingActions actions, @Nullable String text) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).sendMessage(text);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * Set an indefinite hold using the supplied the cool and heat hold temperatures
+ *
+ * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/SetHold.shtml">Set Hold</a>
+ */
+ @RuleAction(label = "set the thermostat into hold", description = "The set hold function sets the thermostat into a hold with the specified temperatures.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
+ @ActionInput(name = "coolHoldTemp", description = "The temperature at which to set the cool hold.") @Nullable QuantityType<Temperature> coolHoldTemp,
+ @ActionInput(name = "heatHoldTemp", description = "The temperature at which to set the heat hold.") @Nullable QuantityType<Temperature> heatHoldTemp) {
+ if (coolHoldTemp == null || heatHoldTemp == null) {
+ throw new IllegalArgumentException("hold temperatures cannot be null");
+ }
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put("coolHoldTemp", coolHoldTemp);
+ params.put("heatHoldTemp", heatHoldTemp);
+ return setHold(params, null, null, null, null);
+ }
+
+ public static boolean setHold(@Nullable ThingActions actions, @Nullable QuantityType<Temperature> coolHoldTemp,
+ @Nullable QuantityType<Temperature> heatHoldTemp) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).setHold(coolHoldTemp, heatHoldTemp);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * Set a hold by providing the cool and heat temperatures and the number of hours.
+ */
+ @RuleAction(label = "set the thermostat into hold", description = "The set hold function sets the thermostat into a hold for the specified number of hours.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
+ @ActionInput(name = "coolHoldTemp", description = "The temperature at which to set the cool hold.") @Nullable QuantityType<Temperature> coolHoldTemp,
+ @ActionInput(name = "heatHoldTemp", description = "The temperature at which to set the heat hold.") @Nullable QuantityType<Temperature> heatHoldTemp,
+ @ActionInput(name = "holdHours", description = "The number of hours for the hold.") @Nullable Number holdHours) {
+ if (coolHoldTemp == null || heatHoldTemp == null) {
+ throw new IllegalArgumentException("hold temperatures cannot be null");
+ }
+ if (holdHours == null) {
+ throw new IllegalArgumentException("number of hold hours is missing");
+ }
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put("coolHoldTemp", coolHoldTemp);
+ params.put("heatHoldTemp", heatHoldTemp);
+ params.put("holdType", HoldType.HOLD_HOURS);
+ params.put("holdHours", Integer.valueOf(holdHours.intValue()));
+ return setHold(params, null, null, null, null);
+ }
+
+ public static boolean setHold(@Nullable ThingActions actions, @Nullable QuantityType<Temperature> coolHoldTemp,
+ @Nullable QuantityType<Temperature> heatHoldTemp, @Nullable Number holdHours) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).setHold(coolHoldTemp, heatHoldTemp, holdHours);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * Set an indefinite hold using the supplied climateRef
+ */
+ @RuleAction(label = "set the thermostat into hold", description = "The set hold function sets the thermostat into a hold with the specified climate ref.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
+ @ActionInput(name = "holdClimateRef", description = "The holdClimateRef used to set the hold.") @Nullable String holdClimateRef) {
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ if (holdClimateRef == null || !localHandler.isValidClimateRef(holdClimateRef)) {
+ throw new IllegalArgumentException("hold climate ref is missing or invalid");
+ }
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put("holdClimateRef", holdClimateRef);
+ return setHold(params, null, null, null, null);
+ }
+
+ public static boolean setHold(@Nullable ThingActions actions, @Nullable String holdClimateRef) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).setHold(holdClimateRef);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * Set a hold using the supplied climateRef for the supplied number of hours.
+ */
+ @RuleAction(label = "set the thermostat into hold", description = "The set hold function sets the thermostat into a hold with the specified climate ref.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
+ @ActionInput(name = "holdClimateRef", description = "The holdClimateRef used to set the hold.") @Nullable String holdClimateRef,
+ @ActionInput(name = "holdHours", description = "The number of hours for the hold.") @Nullable Number holdHours) {
+ if (holdHours == null) {
+ throw new IllegalArgumentException("number of hold hours is missing");
+ }
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ if (holdClimateRef == null || !localHandler.isValidClimateRef(holdClimateRef)) {
+ throw new IllegalArgumentException("hold climate ref is missing or invalid");
+ }
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put("holdClimateRef", holdClimateRef);
+ params.put("holdType", HoldType.HOLD_HOURS);
+ params.put("holdHours", Integer.valueOf(holdHours.intValue()));
+ return setHold(params, null, null, null, null);
+ }
+
+ public static boolean setHold(@Nullable ThingActions actions, @Nullable String holdClimateRef,
+ @Nullable Number holdHours) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).setHold(holdClimateRef, holdHours);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * Set a hold
+ */
+ @RuleAction(label = "set the thermostat into hold", description = "The set hold function sets the thermostat into a hold with the specified temperature or climate ref.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
+ @ActionInput(name = "coolHoldTemp", description = "(opt) The temperature at which to set the cool hold.") @Nullable QuantityType<Temperature> coolHoldTemp,
+ @ActionInput(name = "heatHoldTemp", description = "(opt) The temperature at which to set the heat hold.") @Nullable QuantityType<Temperature> heatHoldTemp,
+ @ActionInput(name = "holdClimateRef", description = "(opt) The Climate to use as reference for setting the coolHoldTemp, heatHoldTemp and fan settings for this hold. If this value is passed the coolHoldTemp and heatHoldTemp are not required.") @Nullable String holdClimateRef,
+ @ActionInput(name = "startDateTime", description = "(opt) The start date in thermostat time.") @Nullable Date startDateTime,
+ @ActionInput(name = "endDateTime", description = "(opt) The end date in thermostat time.") @Nullable Date endDateTime,
+ @ActionInput(name = "holdType", description = "(opt) The hold duration type. Valid values: dateTime, nextTransition, indefinite, holdHours.") @Nullable String holdType,
+ @ActionInput(name = "holdHours", description = "(opt) The number of hours to hold for, used and required if holdType='holdHours'.") @Nullable Number holdHours) {
+ Map<String, Object> params = new HashMap<String, Object>();
+ if (coolHoldTemp != null) {
+ params.put("coolHoldTemp", coolHoldTemp);
+ }
+ if (heatHoldTemp != null) {
+ params.put("heatHoldTemp", heatHoldTemp);
+ }
+ if (holdClimateRef != null) {
+ params.put("holdClimateRef", holdClimateRef);
+ }
+ return setHold(params, holdType, holdHours, startDateTime, endDateTime);
+ }
+
+ public static boolean setHold(@Nullable ThingActions actions, @Nullable QuantityType<Temperature> coolHoldTemp,
+ @Nullable QuantityType<Temperature> heatHoldTemp, @Nullable String holdClimateRef,
+ @Nullable Date startDateTime, @Nullable Date endDateTime, @Nullable String holdType,
+ @Nullable Number holdHours) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).setHold(coolHoldTemp, heatHoldTemp, holdClimateRef, startDateTime,
+ endDateTime, holdType, holdHours);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * Set a hold by providing a parameter map
+ */
+ @RuleAction(label = "set the thermostat into hold", description = "The set hold function sets the thermostat into a hold with the specified event parameters.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setHold(
+ @ActionInput(name = "params", description = "The map of hold parameters.") @Nullable Map<String, Object> params,
+ @ActionInput(name = "holdType", description = "(opt) The hold duration type. Valid values: dateTime, nextTransition, indefinite, holdHours.") @Nullable String holdType,
+ @ActionInput(name = "holdHours", description = "(opt) The number of hours to hold for, used and required if holdType='holdHours'.") @Nullable Number holdHours,
+ @ActionInput(name = "startDateTime", description = "(opt) The start date in thermostat time.") @Nullable Date startDateTime,
+ @ActionInput(name = "endDateTime", description = "(opt) The end date in thermostat time.") @Nullable Date endDateTime) {
+ LOGGER.debug("EcobeeActions: Action 'SetHold' called");
+ if (params == null) {
+ throw new IllegalArgumentException("params cannot be null");
+ }
+ EventDTO event = new EventDTO();
+ for (String key : params.keySet()) {
+ Object value = params.get(key);
+ switch (key) {
+ case "isOccupied":
+ event.isOccupied = ((Boolean) value);
+ break;
+ case "isCoolOff":
+ event.isCoolOff = ((Boolean) value);
+ break;
+ case "isHeatOff":
+ event.isHeatOff = ((Boolean) value);
+ break;
+ case "coolHoldTemp":
+ event.coolHoldTemp = EcobeeUtils.convertQuantityTypeToEcobeeTemp(value);
+ break;
+ case "heatHoldTemp":
+ event.heatHoldTemp = EcobeeUtils.convertQuantityTypeToEcobeeTemp(value);
+ break;
+ case "fan":
+ event.fan = FanMode.forValue((String) value).toString();
+ break;
+ case "vent":
+ event.vent = VentilatorMode.forValue((String) value).toString();
+ break;
+ case "ventilatorMinOnTime":
+ event.ventilatorMinOnTime = ((Integer) value);
+ break;
+ case "isOptional":
+ event.isOptional = ((Boolean) value);
+ break;
+ case "isTemperatureRelative":
+ event.isTemperatureRelative = ((Boolean) value);
+ break;
+ case "coolRelativeTemp":
+ event.coolRelativeTemp = EcobeeUtils.convertQuantityTypeToEcobeeTemp(value);
+ break;
+ case "heatRelativeTemp":
+ event.heatRelativeTemp = EcobeeUtils.convertQuantityTypeToEcobeeTemp(value);
+ break;
+ case "isTemperatureAbsolute":
+ event.isTemperatureAbsolute = ((Boolean) value);
+ break;
+ case "fanMinOnTime":
+ event.fanMinOnTime = ((Integer) value);
+ break;
+ case "holdClimateRef":
+ event.holdClimateRef = ((String) value);
+ break;
+ default:
+ LOGGER.warn("Unrecognized event field '{}' with value '{}' ignored.", key, value);
+ break;
+ }
+ }
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ SetHoldFunction function = new SetHoldFunction(event, (holdType == null) ? null : HoldType.forValue(holdType),
+ (holdHours == null) ? null : holdHours.intValue(), startDateTime, endDateTime);
+ return localHandler.actionPerformFunction(function);
+ }
+
+ public static boolean setHold(@Nullable ThingActions actions, @Nullable Map<String, Object> params,
+ @Nullable String holdType, @Nullable Number holdHours, @Nullable Date startDateTime,
+ @Nullable Date endDateTime) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).setHold(params, holdType, holdHours, startDateTime, endDateTime);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * The set occupied function may only be used by EMS thermostats. The function switches a thermostat from occupied
+ * mode to unoccupied, or vice versa.
+ *
+ * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/SetOccupied.shtml">Set
+ * Occupied</a>
+ */
+ @RuleAction(label = "switch the thermostat occupancy", description = "The function switches a thermostat from occupied mode to unoccupied, or vice versa (EMS MODELS ONLY).")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean setOccupied(
+ @ActionInput(name = "occupied", description = "The climate to use for the temperature, occupied (true) or unoccupied (false).") @Nullable Boolean occupied,
+ @ActionInput(name = "startDateTime", description = "(opt) The start date in thermostat time.") @Nullable Date startDateTime,
+ @ActionInput(name = "endDateTime", description = "(opt) The end date in thermostat time.") @Nullable Date endDateTime,
+ @ActionInput(name = "holdType", description = "(opt) The hold duration type. Valid values: dateTime, nextTransition, indefinite, holdHours.") @Nullable String holdType,
+ @ActionInput(name = "holdHours", description = "(opt) The number of hours to hold for, used and required if holdType='holdHours'.") @Nullable Number holdHours) {
+ LOGGER.debug("EcobeeActions: Action 'Set Occupied' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ SetOccupiedFunction function = new SetOccupiedFunction(occupied, startDateTime, endDateTime,
+ (holdType == null) ? null : HoldType.forValue(holdType),
+ (holdHours == null) ? null : Integer.valueOf(holdHours.intValue()));
+ return localHandler.actionPerformFunction(function);
+ }
+
+ public static boolean setOccupied(@Nullable ThingActions actions, @Nullable Boolean occupied,
+ @Nullable Date startDateTime, @Nullable Date endDateTime, @Nullable String holdType,
+ @Nullable Number holdHours) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).setOccupied(occupied, startDateTime, endDateTime, holdType, holdHours);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * The update sensor function allows the caller to update the name of an ecobee3 remote sensor.
+ *
+ * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/functions/UpdateSensor.shtml">Update
+ * Sensor</a>
+ */
+ @RuleAction(label = "update a remote sensor name", description = "The update sensor function allows the caller to update the name of an ecobee3 remote sensor.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean updateSensor(
+ @ActionInput(name = "name", description = "The updated name to give the sensor. Has a max length of 32, but shorter is recommended.") @Nullable String name,
+ @ActionInput(name = "deviceId", description = "The deviceId for the sensor, typically this indicates the enclosure and corresponds to the ThermostatRemoteSensor.id field. For example: rs:100") @Nullable String deviceId,
+ @ActionInput(name = "sensorId", description = "The identifier for the sensor within the enclosure. Corresponds to the RemoteSensorCapability.id. For example: 1") @Nullable String sensorId) {
+ LOGGER.debug("EcobeeActions: Action 'UpdateSensor' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ UpdateSensorFunction function = new UpdateSensorFunction(name, deviceId, sensorId);
+ return localHandler.actionPerformFunction(function);
+ }
+
+ public static boolean updateSensor(@Nullable ThingActions actions, @Nullable String name, @Nullable String deviceId,
+ @Nullable String sensorId) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).updateSensor(name, deviceId, sensorId);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * Get the alerts list. Returns a JSON string containing all the alerts.
+ */
+ @RuleAction(label = "get the alerts", description = "Get the alerts list.")
+ public @ActionOutput(name = "alerts", type = "java.lang.String") @Nullable String getAlerts() {
+ LOGGER.debug("EcobeeActions: Action 'Get Alerts' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return null;
+ }
+ return localHandler.getAlerts();
+ }
+
+ public static @Nullable String getAlerts(@Nullable ThingActions actions) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).getAlerts();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * Get the events list. Returns a JSON string contains all events.
+ */
+ @RuleAction(label = "get the events", description = "Get the events list.")
+ public @ActionOutput(name = "events", type = "java.lang.String") @Nullable String getEvents() {
+ LOGGER.debug("EcobeeActions: Action 'Get Events' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return null;
+ }
+ return localHandler.getEvents();
+ }
+
+ public static @Nullable String getEvents(@Nullable ThingActions actions) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).getEvents();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+
+ /**
+ * Get a list of climates. Returns a JSON string contains all climates.
+ */
+ @RuleAction(label = "get the climates", description = "Get a list of climates.")
+ public @ActionOutput(name = "climates", type = "java.lang.String") @Nullable String getClimates() {
+ LOGGER.debug("EcobeeActions: Action 'Get Climates' called");
+ EcobeeThermostatBridgeHandler localHandler = handler;
+ if (localHandler == null) {
+ LOGGER.info("EcobeeActions: Action service ThingHandler is null!");
+ return null;
+ }
+ return localHandler.getClimates();
+ }
+
+ public static @Nullable String getClimates(@Nullable ThingActions actions) {
+ if (actions instanceof EcobeeActions) {
+ return ((EcobeeActions) actions).getClimates();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of EcobeeActions");
+ }
+ }
+}
import org.apache.commons.lang.WordUtils;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.ecobee.action.EcobeeActions;
+import org.openhab.binding.ecobee.internal.action.EcobeeActions;
import org.openhab.binding.ecobee.internal.api.EcobeeApi;
import org.openhab.binding.ecobee.internal.config.EcobeeThermostatConfiguration;
import org.openhab.binding.ecobee.internal.discovery.SensorDiscoveryService;
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.enigma2.actions;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.enigma2.handler.Enigma2Handler;
-import org.openhab.binding.enigma2.internal.Enigma2BindingConstants;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-
-/**
- * This is the automation engine actions handler service for the
- * enigma2 actions.
- *
- * @author Guido Dolfen - Initial contribution
- */
-@ThingActionsScope(name = "enigma2")
-@NonNullByDefault
-public class Enigma2Actions implements ThingActions, IEnigma2Actions {
- private @Nullable Enigma2Handler handler;
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- this.handler = (Enigma2Handler) handler;
- }
-
- @Override
- public @Nullable Enigma2Handler getThingHandler() {
- return this.handler;
- }
-
- @Override
- @RuleAction(label = "@text/actions.enigma2.send-rc-button.label", description = "@text/actions.enigma2.send-rc-button.description")
- @SuppressWarnings("null")
- public void sendRcCommand(
- @ActionInput(name = "rcButton", label = "@text/actions-input.enigma2.rc-button.label", description = "@text/actions-input.enigma2.rc-button.description") String rcButton) {
- handler.sendRcCommand(rcButton);
- }
-
- @Override
- @RuleAction(label = "@text/actions.enigma2.send-info.label", description = "@text/actions.enigma2.send-info.description")
- @SuppressWarnings("null")
- public void sendInfo(
- @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text) {
- handler.sendInfo(Enigma2BindingConstants.MESSAGE_TIMEOUT, text);
- }
-
- @Override
- @RuleAction(label = "@text/actions.enigma2.send-info.label", description = "@text/actions.enigma2.send-info.description")
- @SuppressWarnings("null")
- public void sendInfo(
- @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text,
- @ActionInput(name = "timeout", label = "@text/actions-input.enigma2.timeout.label", description = "@text/actions-input.enigma2.timeout.description") int timeout) {
- handler.sendInfo(timeout, text);
- }
-
- @Override
- @RuleAction(label = "@text/actions.enigma2.send-warning.label", description = "@text/actions.enigma2.send-warning.description")
- @SuppressWarnings("null")
- public void sendWarning(
- @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text) {
- handler.sendWarning(Enigma2BindingConstants.MESSAGE_TIMEOUT, text);
- }
-
- @Override
- @RuleAction(label = "@text/actions.enigma2.send-warning.label", description = "@text/actions.enigma2.send-warning.description")
- @SuppressWarnings("null")
- public void sendWarning(
- @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text,
- @ActionInput(name = "timeout", label = "@text/actions-input.enigma2.timeout.label", description = "@text/actions-input.enigma2.timeout.description") int timeout) {
- handler.sendWarning(timeout, text);
- }
-
- @Override
- @RuleAction(label = "@text/actions.enigma2.send-error.label", description = "@text/actions.enigma2.send-error.description")
- @SuppressWarnings("null")
- public void sendError(
- @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text) {
- handler.sendError(Enigma2BindingConstants.MESSAGE_TIMEOUT, text);
- }
-
- @Override
- @RuleAction(label = "@text/actions.enigma2.send-error.label", description = "@text/actions.enigma2.send-error.description")
- @SuppressWarnings("null")
- public void sendError(
- @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text,
- @ActionInput(name = "timeout", label = "@text/actions-input.enigma2.timeout.label", description = "@text/actions-input.enigma2.timeout.description") int timeout) {
- handler.sendError(timeout, text);
- }
-
- @Override
- @RuleAction(label = "@text/actions.enigma2.send-error.label", description = "@text/actions.enigma2.send-question.description")
- @SuppressWarnings("null")
- public void sendQuestion(
- @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text) {
- handler.sendQuestion(Enigma2BindingConstants.MESSAGE_TIMEOUT, text);
- }
-
- @Override
- @RuleAction(label = "@text/actions.enigma2.send-error.label", description = "@text/actions.enigma2.send-question.description")
- @SuppressWarnings("null")
- public void sendQuestion(
- @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text,
- @ActionInput(name = "timeout", label = "@text/actions-input.enigma2.timeout.label", description = "@text/actions-input.enigma2.timeout.description") int timeout) {
- handler.sendQuestion(timeout, text);
- }
-
- // delegation methods for "legacy" rule support
- public static void sendRcCommand(@Nullable ThingActions actions, String rcButton) {
- invokeMethodOf(actions).sendRcCommand(rcButton);
- }
-
- public static void sendInfo(@Nullable ThingActions actions, String info) {
- invokeMethodOf(actions).sendInfo(info);
- }
-
- public static void sendInfo(@Nullable ThingActions actions, String info, int timeout) {
- invokeMethodOf(actions).sendInfo(info, timeout);
- }
-
- public static void sendWarning(@Nullable ThingActions actions, String warning) {
- invokeMethodOf(actions).sendWarning(warning);
- }
-
- public static void sendWarning(@Nullable ThingActions actions, String warning, int timeout) {
- invokeMethodOf(actions).sendWarning(warning, timeout);
- }
-
- public static void sendError(@Nullable ThingActions actions, String error) {
- invokeMethodOf(actions).sendError(error);
- }
-
- public static void sendError(@Nullable ThingActions actions, String error, int timeout) {
- invokeMethodOf(actions).sendError(error, timeout);
- }
-
- public static void sendQuestion(@Nullable ThingActions actions, String text) {
- invokeMethodOf(actions).sendQuestion(text);
- }
-
- public static void sendQuestion(@Nullable ThingActions actions, String text, int timeout) {
- invokeMethodOf(actions).sendQuestion(text, timeout);
- }
-
- private static IEnigma2Actions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(Enigma2Actions.class.getName())) {
- if (actions instanceof IEnigma2Actions) {
- return (IEnigma2Actions) actions;
- } else {
- return (IEnigma2Actions) Proxy.newProxyInstance(IEnigma2Actions.class.getClassLoader(),
- new Class[] { IEnigma2Actions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of Enigma2Actions");
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.enigma2.actions;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * The {@link IEnigma2Actions} defines the interface for all thing actions supported by the binding.
- *
- * @author Guido Dolfen - Initial contribution
- */
-@NonNullByDefault
-public interface IEnigma2Actions {
- void sendRcCommand(String rcButton);
-
- void sendInfo(String text);
-
- void sendInfo(String text, int timeout);
-
- void sendWarning(String text);
-
- void sendWarning(String text, int timeout);
-
- void sendError(String text);
-
- void sendError(String text, int timeout);
-
- void sendQuestion(String text);
-
- void sendQuestion(String text, int timeout);
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.enigma2.handler;
-
-import static org.openhab.binding.enigma2.internal.Enigma2BindingConstants.*;
-
-import java.time.LocalDateTime;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Optional;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.enigma2.actions.Enigma2Actions;
-import org.openhab.binding.enigma2.internal.Enigma2Client;
-import org.openhab.binding.enigma2.internal.Enigma2Configuration;
-import org.openhab.binding.enigma2.internal.Enigma2RemoteKey;
-import org.openhab.core.library.types.*;
-import org.openhab.core.thing.ChannelUID;
-import org.openhab.core.thing.Thing;
-import org.openhab.core.thing.ThingStatus;
-import org.openhab.core.thing.ThingStatusDetail;
-import org.openhab.core.thing.binding.BaseThingHandler;
-import org.openhab.core.thing.binding.ThingHandlerService;
-import org.openhab.core.types.Command;
-import org.openhab.core.types.RefreshType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link Enigma2Handler} is responsible for handling commands, which are
- * sent to one of the channels.
- *
- * @author Guido Dolfen - Initial contribution
- */
-@NonNullByDefault
-public class Enigma2Handler extends BaseThingHandler {
- private final Logger logger = LoggerFactory.getLogger(Enigma2Handler.class);
- private Enigma2Configuration configuration = new Enigma2Configuration();
- private Optional<Enigma2Client> enigma2Client = Optional.empty();
- private @Nullable ScheduledFuture<?> refreshJob;
- private LocalDateTime lastAnswerTime = LocalDateTime.now();
-
- public Enigma2Handler(Thing thing) {
- super(thing);
- }
-
- @Override
- public void initialize() {
- configuration = getConfigAs(Enigma2Configuration.class);
- if (configuration.host.isEmpty()) {
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "host must not be empty");
- } else if (configuration.timeout <= 0 || configuration.timeout > 300) {
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
- "timeout must be between 0 and 300 seconds");
- } else if (configuration.refreshInterval <= 0 || configuration.refreshInterval > 3600) {
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
- "refreshInterval must be between 0 and 3600 seconds");
- }
- enigma2Client = Optional.of(new Enigma2Client(configuration.host, configuration.user, configuration.password,
- configuration.timeout));
- refreshJob = scheduler.scheduleWithFixedDelay(this::refresh, 2, configuration.refreshInterval,
- TimeUnit.SECONDS);
- }
-
- private void refresh() {
- getEnigma2Client().ifPresent(client -> {
- boolean online = client.refresh();
- if (online) {
- updateStatus(ThingStatus.ONLINE);
- updateState(CHANNEL_POWER, client.isPower() ? OnOffType.ON : OnOffType.OFF);
- updateState(CHANNEL_MUTE, client.isMute() ? OnOffType.ON : OnOffType.OFF);
- updateState(CHANNEL_VOLUME, new PercentType(client.getVolume()));
- updateState(CHANNEL_CHANNEL, new StringType(client.getChannel()));
- updateState(CHANNEL_TITLE, new StringType(client.getTitle()));
- updateState(CHANNEL_DESCRIPTION, new StringType(client.getDescription()));
- if (lastAnswerTime.isBefore(client.getLastAnswerTime())) {
- lastAnswerTime = client.getLastAnswerTime();
- updateState(CHANNEL_ANSWER, new StringType(client.getAnswer()));
- }
- } else {
- updateStatus(ThingStatus.OFFLINE);
- }
- });
- }
-
- @Override
- public void dispose() {
- ScheduledFuture<?> job = this.refreshJob;
- if (job != null) {
- job.cancel(true);
- }
- this.refreshJob = null;
- }
-
- @Override
- public void handleCommand(ChannelUID channelUID, Command command) {
- logger.debug("handleCommand({},{})", channelUID, command);
- getEnigma2Client().ifPresent(client -> {
- switch (channelUID.getId()) {
- case CHANNEL_POWER:
- handlePower(channelUID, command, client);
- break;
- case CHANNEL_CHANNEL:
- handleChannel(channelUID, command, client);
- break;
- case CHANNEL_MEDIA_PLAYER:
- handleMediaPlayer(channelUID, command);
- break;
- case CHANNEL_MEDIA_STOP:
- handleMediaStop(channelUID, command);
- break;
- case CHANNEL_MUTE:
- handleMute(channelUID, command, client);
- break;
- case CHANNEL_VOLUME:
- handleVolume(channelUID, command, client);
- break;
- case CHANNEL_TITLE:
- handleTitle(channelUID, command, client);
- break;
- case CHANNEL_DESCRIPTION:
- handleDescription(channelUID, command, client);
- break;
- case CHANNEL_ANSWER:
- handleAnswer(channelUID, command, client);
- break;
- default:
- logger.debug("Channel {} is not supported", channelUID);
- break;
- }
- });
- }
-
- private void handleVolume(ChannelUID channelUID, Command command, Enigma2Client client) {
- if (command instanceof RefreshType) {
- client.refreshVolume();
- updateState(channelUID, new PercentType(client.getVolume()));
- } else if (command instanceof PercentType) {
- client.setVolume(((PercentType) command).intValue());
- } else if (command instanceof DecimalType) {
- client.setVolume(((DecimalType) command).intValue());
- } else {
- logger.info("Channel {} only accepts PercentType, DecimalType, RefreshType. Type was {}.", channelUID,
- command.getClass());
- }
- }
-
- private void handleMute(ChannelUID channelUID, Command command, Enigma2Client client) {
- if (command instanceof RefreshType) {
- client.refreshVolume();
- updateState(channelUID, client.isMute() ? OnOffType.ON : OnOffType.OFF);
- } else if (OnOffType.ON.equals(command)) {
- client.setMute(true);
- } else if (OnOffType.OFF.equals(command)) {
- client.setMute(false);
- } else {
- logger.info("Channel {} only accepts OnOffType, RefreshType. Type was {}.", channelUID, command.getClass());
- }
- }
-
- private void handleAnswer(ChannelUID channelUID, Command command, Enigma2Client client) {
- if (command instanceof RefreshType) {
- client.refreshAnswer();
- if (lastAnswerTime.isBefore(client.getLastAnswerTime())) {
- lastAnswerTime = client.getLastAnswerTime();
- updateState(channelUID, new StringType(client.getAnswer()));
- }
- } else {
- logger.info("Channel {} only accepts RefreshType. Type was {}.", channelUID, command.getClass());
- }
- }
-
- private void handleMediaStop(ChannelUID channelUID, Command command) {
- if (command instanceof RefreshType) {
- return;
- } else if (command instanceof OnOffType) {
- sendRcCommand(Enigma2RemoteKey.STOP);
- } else {
- logger.info("Channel {} only accepts OnOffType, RefreshType. Type was {}.", channelUID, command.getClass());
- }
- }
-
- private void handleMediaPlayer(ChannelUID channelUID, Command command) {
- if (RefreshType.REFRESH == command) {
- return;
- } else if (PlayPauseType.PLAY == command) {
- sendRcCommand(Enigma2RemoteKey.PLAY);
- } else if (PlayPauseType.PAUSE == command) {
- sendRcCommand(Enigma2RemoteKey.PAUSE);
- } else if (NextPreviousType.NEXT == command) {
- sendRcCommand(Enigma2RemoteKey.FAST_FORWARD);
- } else if (NextPreviousType.PREVIOUS == command) {
- sendRcCommand(Enigma2RemoteKey.FAST_BACKWARD);
- } else {
- logger.info("Channel {} only accepts PlayPauseType, NextPreviousType, RefreshType. Type was {}.",
- channelUID, command.getClass());
- }
- }
-
- private void handleChannel(ChannelUID channelUID, Command command, Enigma2Client client) {
- if (command instanceof RefreshType) {
- client.refreshChannel();
- updateState(channelUID, new StringType(client.getChannel()));
- } else if (command instanceof StringType) {
- client.setChannel(command.toString());
- } else {
- logger.info("Channel {} only accepts StringType, RefreshType. Type was {}.", channelUID,
- command.getClass());
- }
- }
-
- private void handleTitle(ChannelUID channelUID, Command command, Enigma2Client client) {
- if (command instanceof RefreshType) {
- client.refreshEpg();
- updateState(channelUID, new StringType(client.getTitle()));
- } else {
- logger.info("Channel {} only accepts RefreshType. Type was {}.", channelUID, command.getClass());
- }
- }
-
- private void handleDescription(ChannelUID channelUID, Command command, Enigma2Client client) {
- if (command instanceof RefreshType) {
- client.refreshEpg();
- updateState(channelUID, new StringType(client.getDescription()));
- } else {
- logger.info("Channel {} only accepts RefreshType. Type was {}.", channelUID, command.getClass());
- }
- }
-
- private void handlePower(ChannelUID channelUID, Command command, Enigma2Client client) {
- if (RefreshType.REFRESH == command) {
- client.refreshPower();
- updateState(channelUID, client.isPower() ? OnOffType.ON : OnOffType.OFF);
- } else if (OnOffType.ON == command) {
- client.setPower(true);
- } else if (OnOffType.OFF == command) {
- client.setPower(false);
- } else {
- logger.info("Channel {} only accepts OnOffType, RefreshType. Type was {}.", channelUID, command.getClass());
- }
- }
-
- public void sendRcCommand(String rcButton) {
- logger.debug("sendRcCommand({})", rcButton);
- try {
- Enigma2RemoteKey remoteKey = Enigma2RemoteKey.valueOf(rcButton);
- sendRcCommand(remoteKey);
- } catch (IllegalArgumentException ex) {
- logger.warn("{} is not a valid value for button - available are: {}", rcButton,
- Stream.of(Enigma2RemoteKey.values()).map(b -> b.name()).collect(Collectors.joining(", ")));
- }
- }
-
- private void sendRcCommand(Enigma2RemoteKey remoteKey) {
- getEnigma2Client().ifPresent(client -> client.sendRcCommand(remoteKey.getValue()));
- }
-
- public void sendInfo(int timeout, String text) {
- getEnigma2Client().ifPresent(client -> client.sendInfo(timeout, text));
- }
-
- public void sendWarning(int timeout, String text) {
- getEnigma2Client().ifPresent(client -> client.sendWarning(timeout, text));
- }
-
- public void sendError(int timeout, String text) {
- getEnigma2Client().ifPresent(client -> client.sendError(timeout, text));
- }
-
- public void sendQuestion(int timeout, String text) {
- getEnigma2Client().ifPresent(client -> client.sendQuestion(timeout, text));
- }
-
- @Override
- public Collection<Class<? extends ThingHandlerService>> getServices() {
- return Collections.singleton(Enigma2Actions.class);
- }
-
- /**
- * Getter for Test-Injection
- *
- * @return Enigma2Client.
- */
- Optional<Enigma2Client> getEnigma2Client() {
- return enigma2Client;
- }
-}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.enigma2.handler.Enigma2Handler;
+import org.openhab.binding.enigma2.internal.handler.Enigma2Handler;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.enigma2.internal.actions;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.enigma2.internal.Enigma2BindingConstants;
+import org.openhab.binding.enigma2.internal.handler.Enigma2Handler;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+
+/**
+ * This is the automation engine actions handler service for the
+ * enigma2 actions.
+ *
+ * @author Guido Dolfen - Initial contribution
+ */
+@ThingActionsScope(name = "enigma2")
+@NonNullByDefault
+public class Enigma2Actions implements ThingActions {
+ private @Nullable Enigma2Handler handler;
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ this.handler = (Enigma2Handler) handler;
+ }
+
+ @Override
+ public @Nullable Enigma2Handler getThingHandler() {
+ return handler;
+ }
+
+ @RuleAction(label = "@text/actions.enigma2.send-rc-button.label", description = "@text/actions.enigma2.send-rc-button.description")
+ @SuppressWarnings("null")
+ public void sendRcCommand(
+ @ActionInput(name = "rcButton", label = "@text/actions-input.enigma2.rc-button.label", description = "@text/actions-input.enigma2.rc-button.description") String rcButton) {
+ handler.sendRcCommand(rcButton);
+ }
+
+ @RuleAction(label = "@text/actions.enigma2.send-info.label", description = "@text/actions.enigma2.send-info.description")
+ @SuppressWarnings("null")
+ public void sendInfo(
+ @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text) {
+ handler.sendInfo(Enigma2BindingConstants.MESSAGE_TIMEOUT, text);
+ }
+
+ @RuleAction(label = "@text/actions.enigma2.send-info.label", description = "@text/actions.enigma2.send-info.description")
+ @SuppressWarnings("null")
+ public void sendInfo(
+ @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text,
+ @ActionInput(name = "timeout", label = "@text/actions-input.enigma2.timeout.label", description = "@text/actions-input.enigma2.timeout.description") int timeout) {
+ handler.sendInfo(timeout, text);
+ }
+
+ @RuleAction(label = "@text/actions.enigma2.send-warning.label", description = "@text/actions.enigma2.send-warning.description")
+ @SuppressWarnings("null")
+ public void sendWarning(
+ @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text) {
+ handler.sendWarning(Enigma2BindingConstants.MESSAGE_TIMEOUT, text);
+ }
+
+ @RuleAction(label = "@text/actions.enigma2.send-warning.label", description = "@text/actions.enigma2.send-warning.description")
+ @SuppressWarnings("null")
+ public void sendWarning(
+ @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text,
+ @ActionInput(name = "timeout", label = "@text/actions-input.enigma2.timeout.label", description = "@text/actions-input.enigma2.timeout.description") int timeout) {
+ handler.sendWarning(timeout, text);
+ }
+
+ @RuleAction(label = "@text/actions.enigma2.send-error.label", description = "@text/actions.enigma2.send-error.description")
+ @SuppressWarnings("null")
+ public void sendError(
+ @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text) {
+ handler.sendError(Enigma2BindingConstants.MESSAGE_TIMEOUT, text);
+ }
+
+ @RuleAction(label = "@text/actions.enigma2.send-error.label", description = "@text/actions.enigma2.send-error.description")
+ @SuppressWarnings("null")
+ public void sendError(
+ @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text,
+ @ActionInput(name = "timeout", label = "@text/actions-input.enigma2.timeout.label", description = "@text/actions-input.enigma2.timeout.description") int timeout) {
+ handler.sendError(timeout, text);
+ }
+
+ @RuleAction(label = "@text/actions.enigma2.send-error.label", description = "@text/actions.enigma2.send-question.description")
+ @SuppressWarnings("null")
+ public void sendQuestion(
+ @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text) {
+ handler.sendQuestion(Enigma2BindingConstants.MESSAGE_TIMEOUT, text);
+ }
+
+ @RuleAction(label = "@text/actions.enigma2.send-error.label", description = "@text/actions.enigma2.send-question.description")
+ @SuppressWarnings("null")
+ public void sendQuestion(
+ @ActionInput(name = "text", label = "@text/actions-input.enigma2.text.label", description = "@text/actions-input.enigma2.text.description") String text,
+ @ActionInput(name = "timeout", label = "@text/actions-input.enigma2.timeout.label", description = "@text/actions-input.enigma2.timeout.description") int timeout) {
+ handler.sendQuestion(timeout, text);
+ }
+
+ // delegation methods for "legacy" rule support
+ public static void sendRcCommand(@Nullable ThingActions actions, String rcButton) {
+ if (actions instanceof Enigma2Actions) {
+ ((Enigma2Actions) actions).sendRcCommand(rcButton);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of Enigma2Actions");
+ }
+ }
+
+ public static void sendInfo(@Nullable ThingActions actions, String info) {
+ if (actions instanceof Enigma2Actions) {
+ ((Enigma2Actions) actions).sendInfo(info);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of Enigma2Actions");
+ }
+ }
+
+ public static void sendInfo(@Nullable ThingActions actions, String info, int timeout) {
+ if (actions instanceof Enigma2Actions) {
+ ((Enigma2Actions) actions).sendInfo(info, timeout);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of Enigma2Actions");
+ }
+ }
+
+ public static void sendWarning(@Nullable ThingActions actions, String warning) {
+ if (actions instanceof Enigma2Actions) {
+ ((Enigma2Actions) actions).sendWarning(warning);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of Enigma2Actions");
+ }
+ }
+
+ public static void sendWarning(@Nullable ThingActions actions, String warning, int timeout) {
+ if (actions instanceof Enigma2Actions) {
+ ((Enigma2Actions) actions).sendWarning(warning, timeout);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of Enigma2Actions");
+ }
+ }
+
+ public static void sendError(@Nullable ThingActions actions, String error) {
+ if (actions instanceof Enigma2Actions) {
+ ((Enigma2Actions) actions).sendError(error);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of Enigma2Actions");
+ }
+ }
+
+ public static void sendError(@Nullable ThingActions actions, String error, int timeout) {
+ if (actions instanceof Enigma2Actions) {
+ ((Enigma2Actions) actions).sendError(error, timeout);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of Enigma2Actions");
+ }
+ }
+
+ public static void sendQuestion(@Nullable ThingActions actions, String text) {
+ if (actions instanceof Enigma2Actions) {
+ ((Enigma2Actions) actions).sendQuestion(text);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of Enigma2Actions");
+ }
+ }
+
+ public static void sendQuestion(@Nullable ThingActions actions, String text, int timeout) {
+ if (actions instanceof Enigma2Actions) {
+ ((Enigma2Actions) actions).sendQuestion(text, timeout);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of Enigma2Actions");
+ }
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.enigma2.internal.handler;
+
+import static org.openhab.binding.enigma2.internal.Enigma2BindingConstants.*;
+
+import java.time.LocalDateTime;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.enigma2.internal.Enigma2Client;
+import org.openhab.binding.enigma2.internal.Enigma2Configuration;
+import org.openhab.binding.enigma2.internal.Enigma2RemoteKey;
+import org.openhab.binding.enigma2.internal.actions.Enigma2Actions;
+import org.openhab.core.library.types.*;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.binding.BaseThingHandler;
+import org.openhab.core.thing.binding.ThingHandlerService;
+import org.openhab.core.types.Command;
+import org.openhab.core.types.RefreshType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link Enigma2Handler} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Guido Dolfen - Initial contribution
+ */
+@NonNullByDefault
+public class Enigma2Handler extends BaseThingHandler {
+ private final Logger logger = LoggerFactory.getLogger(Enigma2Handler.class);
+ private Enigma2Configuration configuration = new Enigma2Configuration();
+ private Optional<Enigma2Client> enigma2Client = Optional.empty();
+ private @Nullable ScheduledFuture<?> refreshJob;
+ private LocalDateTime lastAnswerTime = LocalDateTime.now();
+
+ public Enigma2Handler(Thing thing) {
+ super(thing);
+ }
+
+ @Override
+ public void initialize() {
+ configuration = getConfigAs(Enigma2Configuration.class);
+ if (configuration.host.isEmpty()) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "host must not be empty");
+ } else if (configuration.timeout <= 0 || configuration.timeout > 300) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
+ "timeout must be between 0 and 300 seconds");
+ } else if (configuration.refreshInterval <= 0 || configuration.refreshInterval > 3600) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
+ "refreshInterval must be between 0 and 3600 seconds");
+ }
+ enigma2Client = Optional.of(new Enigma2Client(configuration.host, configuration.user, configuration.password,
+ configuration.timeout));
+ refreshJob = scheduler.scheduleWithFixedDelay(this::refresh, 2, configuration.refreshInterval,
+ TimeUnit.SECONDS);
+ }
+
+ private void refresh() {
+ getEnigma2Client().ifPresent(client -> {
+ boolean online = client.refresh();
+ if (online) {
+ updateStatus(ThingStatus.ONLINE);
+ updateState(CHANNEL_POWER, client.isPower() ? OnOffType.ON : OnOffType.OFF);
+ updateState(CHANNEL_MUTE, client.isMute() ? OnOffType.ON : OnOffType.OFF);
+ updateState(CHANNEL_VOLUME, new PercentType(client.getVolume()));
+ updateState(CHANNEL_CHANNEL, new StringType(client.getChannel()));
+ updateState(CHANNEL_TITLE, new StringType(client.getTitle()));
+ updateState(CHANNEL_DESCRIPTION, new StringType(client.getDescription()));
+ if (lastAnswerTime.isBefore(client.getLastAnswerTime())) {
+ lastAnswerTime = client.getLastAnswerTime();
+ updateState(CHANNEL_ANSWER, new StringType(client.getAnswer()));
+ }
+ } else {
+ updateStatus(ThingStatus.OFFLINE);
+ }
+ });
+ }
+
+ @Override
+ public void dispose() {
+ ScheduledFuture<?> job = this.refreshJob;
+ if (job != null) {
+ job.cancel(true);
+ }
+ this.refreshJob = null;
+ }
+
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ logger.debug("handleCommand({},{})", channelUID, command);
+ getEnigma2Client().ifPresent(client -> {
+ switch (channelUID.getId()) {
+ case CHANNEL_POWER:
+ handlePower(channelUID, command, client);
+ break;
+ case CHANNEL_CHANNEL:
+ handleChannel(channelUID, command, client);
+ break;
+ case CHANNEL_MEDIA_PLAYER:
+ handleMediaPlayer(channelUID, command);
+ break;
+ case CHANNEL_MEDIA_STOP:
+ handleMediaStop(channelUID, command);
+ break;
+ case CHANNEL_MUTE:
+ handleMute(channelUID, command, client);
+ break;
+ case CHANNEL_VOLUME:
+ handleVolume(channelUID, command, client);
+ break;
+ case CHANNEL_TITLE:
+ handleTitle(channelUID, command, client);
+ break;
+ case CHANNEL_DESCRIPTION:
+ handleDescription(channelUID, command, client);
+ break;
+ case CHANNEL_ANSWER:
+ handleAnswer(channelUID, command, client);
+ break;
+ default:
+ logger.debug("Channel {} is not supported", channelUID);
+ break;
+ }
+ });
+ }
+
+ private void handleVolume(ChannelUID channelUID, Command command, Enigma2Client client) {
+ if (command instanceof RefreshType) {
+ client.refreshVolume();
+ updateState(channelUID, new PercentType(client.getVolume()));
+ } else if (command instanceof PercentType) {
+ client.setVolume(((PercentType) command).intValue());
+ } else if (command instanceof DecimalType) {
+ client.setVolume(((DecimalType) command).intValue());
+ } else {
+ logger.info("Channel {} only accepts PercentType, DecimalType, RefreshType. Type was {}.", channelUID,
+ command.getClass());
+ }
+ }
+
+ private void handleMute(ChannelUID channelUID, Command command, Enigma2Client client) {
+ if (command instanceof RefreshType) {
+ client.refreshVolume();
+ updateState(channelUID, client.isMute() ? OnOffType.ON : OnOffType.OFF);
+ } else if (OnOffType.ON.equals(command)) {
+ client.setMute(true);
+ } else if (OnOffType.OFF.equals(command)) {
+ client.setMute(false);
+ } else {
+ logger.info("Channel {} only accepts OnOffType, RefreshType. Type was {}.", channelUID, command.getClass());
+ }
+ }
+
+ private void handleAnswer(ChannelUID channelUID, Command command, Enigma2Client client) {
+ if (command instanceof RefreshType) {
+ client.refreshAnswer();
+ if (lastAnswerTime.isBefore(client.getLastAnswerTime())) {
+ lastAnswerTime = client.getLastAnswerTime();
+ updateState(channelUID, new StringType(client.getAnswer()));
+ }
+ } else {
+ logger.info("Channel {} only accepts RefreshType. Type was {}.", channelUID, command.getClass());
+ }
+ }
+
+ private void handleMediaStop(ChannelUID channelUID, Command command) {
+ if (command instanceof RefreshType) {
+ return;
+ } else if (command instanceof OnOffType) {
+ sendRcCommand(Enigma2RemoteKey.STOP);
+ } else {
+ logger.info("Channel {} only accepts OnOffType, RefreshType. Type was {}.", channelUID, command.getClass());
+ }
+ }
+
+ private void handleMediaPlayer(ChannelUID channelUID, Command command) {
+ if (RefreshType.REFRESH == command) {
+ return;
+ } else if (PlayPauseType.PLAY == command) {
+ sendRcCommand(Enigma2RemoteKey.PLAY);
+ } else if (PlayPauseType.PAUSE == command) {
+ sendRcCommand(Enigma2RemoteKey.PAUSE);
+ } else if (NextPreviousType.NEXT == command) {
+ sendRcCommand(Enigma2RemoteKey.FAST_FORWARD);
+ } else if (NextPreviousType.PREVIOUS == command) {
+ sendRcCommand(Enigma2RemoteKey.FAST_BACKWARD);
+ } else {
+ logger.info("Channel {} only accepts PlayPauseType, NextPreviousType, RefreshType. Type was {}.",
+ channelUID, command.getClass());
+ }
+ }
+
+ private void handleChannel(ChannelUID channelUID, Command command, Enigma2Client client) {
+ if (command instanceof RefreshType) {
+ client.refreshChannel();
+ updateState(channelUID, new StringType(client.getChannel()));
+ } else if (command instanceof StringType) {
+ client.setChannel(command.toString());
+ } else {
+ logger.info("Channel {} only accepts StringType, RefreshType. Type was {}.", channelUID,
+ command.getClass());
+ }
+ }
+
+ private void handleTitle(ChannelUID channelUID, Command command, Enigma2Client client) {
+ if (command instanceof RefreshType) {
+ client.refreshEpg();
+ updateState(channelUID, new StringType(client.getTitle()));
+ } else {
+ logger.info("Channel {} only accepts RefreshType. Type was {}.", channelUID, command.getClass());
+ }
+ }
+
+ private void handleDescription(ChannelUID channelUID, Command command, Enigma2Client client) {
+ if (command instanceof RefreshType) {
+ client.refreshEpg();
+ updateState(channelUID, new StringType(client.getDescription()));
+ } else {
+ logger.info("Channel {} only accepts RefreshType. Type was {}.", channelUID, command.getClass());
+ }
+ }
+
+ private void handlePower(ChannelUID channelUID, Command command, Enigma2Client client) {
+ if (RefreshType.REFRESH == command) {
+ client.refreshPower();
+ updateState(channelUID, client.isPower() ? OnOffType.ON : OnOffType.OFF);
+ } else if (OnOffType.ON == command) {
+ client.setPower(true);
+ } else if (OnOffType.OFF == command) {
+ client.setPower(false);
+ } else {
+ logger.info("Channel {} only accepts OnOffType, RefreshType. Type was {}.", channelUID, command.getClass());
+ }
+ }
+
+ public void sendRcCommand(String rcButton) {
+ logger.debug("sendRcCommand({})", rcButton);
+ try {
+ Enigma2RemoteKey remoteKey = Enigma2RemoteKey.valueOf(rcButton);
+ sendRcCommand(remoteKey);
+ } catch (IllegalArgumentException ex) {
+ logger.warn("{} is not a valid value for button - available are: {}", rcButton,
+ Stream.of(Enigma2RemoteKey.values()).map(b -> b.name()).collect(Collectors.joining(", ")));
+ }
+ }
+
+ private void sendRcCommand(Enigma2RemoteKey remoteKey) {
+ getEnigma2Client().ifPresent(client -> client.sendRcCommand(remoteKey.getValue()));
+ }
+
+ public void sendInfo(int timeout, String text) {
+ getEnigma2Client().ifPresent(client -> client.sendInfo(timeout, text));
+ }
+
+ public void sendWarning(int timeout, String text) {
+ getEnigma2Client().ifPresent(client -> client.sendWarning(timeout, text));
+ }
+
+ public void sendError(int timeout, String text) {
+ getEnigma2Client().ifPresent(client -> client.sendError(timeout, text));
+ }
+
+ public void sendQuestion(int timeout, String text) {
+ getEnigma2Client().ifPresent(client -> client.sendQuestion(timeout, text));
+ }
+
+ @Override
+ public Collection<Class<? extends ThingHandlerService>> getServices() {
+ return Collections.singleton(Enigma2Actions.class);
+ }
+
+ /**
+ * Getter for Test-Injection
+ *
+ * @return Enigma2Client.
+ */
+ Optional<Enigma2Client> getEnigma2Client() {
+ return enigma2Client;
+ }
+}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.enigma2.actions;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.*;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.openhab.binding.enigma2.handler.Enigma2Handler;
-import org.openhab.binding.enigma2.internal.Enigma2BindingConstants;
-
-/**
- * The {@link Enigma2ActionsTest} class is responsible for testing {@link Enigma2Actions}.
- *
- * @author Guido Dolfen - Initial contribution
- */
-@SuppressWarnings("null")
-@NonNullByDefault
-public class Enigma2ActionsTest {
- @Nullable
- private Enigma2Actions enigma2Actions;
- @Nullable
- private Enigma2Handler enigma2Handler;
- public static final String SOME_TEXT = "some Text";
-
- @BeforeEach
- public void setUp() {
- enigma2Handler = mock(Enigma2Handler.class);
- enigma2Actions = new Enigma2Actions();
- enigma2Actions.setThingHandler(enigma2Handler);
- }
-
- @Test
- public void testGetThingHandler() {
- assertThat(enigma2Actions.getThingHandler(), is(enigma2Handler));
- }
-
- @Test
- public void testSendRcCommand() {
- enigma2Actions.sendRcCommand("KEY_1");
- verify(enigma2Handler).sendRcCommand("KEY_1");
- }
-
- @Test
- public void testSendInfo() {
- enigma2Actions.sendInfo(SOME_TEXT);
- verify(enigma2Handler).sendInfo(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testSendInfoTimeout() {
- enigma2Actions.sendInfo(SOME_TEXT, 10);
- verify(enigma2Handler).sendInfo(10, SOME_TEXT);
- }
-
- @Test
- public void testSendError() {
- enigma2Actions.sendError(SOME_TEXT);
- verify(enigma2Handler).sendError(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testSendErrorTimeout() {
- enigma2Actions.sendError(SOME_TEXT, 10);
- verify(enigma2Handler).sendError(10, SOME_TEXT);
- }
-
- @Test
- public void testSendWarning() {
- enigma2Actions.sendWarning(SOME_TEXT);
- verify(enigma2Handler).sendWarning(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testSendWarningTimeout() {
- enigma2Actions.sendWarning(SOME_TEXT, 10);
- verify(enigma2Handler).sendWarning(10, SOME_TEXT);
- }
-
- @Test
- public void testSendQuestion() {
- enigma2Actions.sendQuestion(SOME_TEXT);
- verify(enigma2Handler).sendQuestion(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testSendQuestionTimeout() {
- enigma2Actions.sendQuestion(SOME_TEXT, 10);
- verify(enigma2Handler).sendQuestion(10, SOME_TEXT);
- }
-
- @Test
- public void testSendRcCommandStatic() {
- Enigma2Actions.sendRcCommand(enigma2Actions, "KEY_1");
- verify(enigma2Handler).sendRcCommand("KEY_1");
- }
-
- @Test
- public void testSendRcCommandStaticWithException() {
- assertThrows(IllegalArgumentException.class, () -> Enigma2Actions.sendRcCommand(null, "KEY_1"));
- }
-
- @Test
- public void testSendInfoStatic() {
- Enigma2Actions.sendInfo(enigma2Actions, SOME_TEXT);
- verify(enigma2Handler).sendInfo(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testSendInfoTimeoutStatic() {
- Enigma2Actions.sendInfo(enigma2Actions, SOME_TEXT, 10);
- verify(enigma2Handler).sendInfo(10, SOME_TEXT);
- }
-
- @Test
- public void testSendInfoStaticWithException() {
- assertThrows(IllegalArgumentException.class, () -> Enigma2Actions.sendInfo(null, SOME_TEXT));
- }
-
- @Test
- public void testSendErrorStatic() {
- Enigma2Actions.sendError(enigma2Actions, SOME_TEXT);
- verify(enigma2Handler).sendError(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testSendErrorTimeoutStatic() {
- Enigma2Actions.sendError(enigma2Actions, SOME_TEXT, 10);
- verify(enigma2Handler).sendError(10, SOME_TEXT);
- }
-
- @Test
- public void testSendErrorStaticWithException() {
- assertThrows(IllegalArgumentException.class, () -> Enigma2Actions.sendError(null, SOME_TEXT));
- }
-
- @Test
- public void testSendWarningStatic() {
- Enigma2Actions.sendWarning(enigma2Actions, SOME_TEXT);
- verify(enigma2Handler).sendWarning(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testSendWarningTimeoutStatic() {
- Enigma2Actions.sendWarning(enigma2Actions, SOME_TEXT, 10);
- verify(enigma2Handler).sendWarning(10, SOME_TEXT);
- }
-
- @Test
- public void testSendWarningStaticWithException() {
- assertThrows(IllegalArgumentException.class, () -> Enigma2Actions.sendWarning(null, SOME_TEXT));
- }
-
- @Test
- public void testSendQuestionStatic() {
- Enigma2Actions.sendQuestion(enigma2Actions, SOME_TEXT);
- verify(enigma2Handler).sendQuestion(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testSendQuestionTimeoutStatic() {
- Enigma2Actions.sendQuestion(enigma2Actions, SOME_TEXT, 10);
- verify(enigma2Handler).sendQuestion(10, SOME_TEXT);
- }
-
- @Test
- public void testSendQuestionStaticWithException() {
- assertThrows(IllegalArgumentException.class, () -> Enigma2Actions.sendQuestion(null, SOME_TEXT));
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.enigma2.handler;
-
-import static org.eclipse.jdt.annotation.Checks.requireNonNull;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.*;
-import static org.mockito.Mockito.*;
-
-import java.time.LocalDateTime;
-import java.time.temporal.ChronoUnit;
-import java.util.Optional;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.openhab.binding.enigma2.actions.Enigma2Actions;
-import org.openhab.binding.enigma2.internal.Enigma2BindingConstants;
-import org.openhab.binding.enigma2.internal.Enigma2Client;
-import org.openhab.binding.enigma2.internal.Enigma2Configuration;
-import org.openhab.binding.enigma2.internal.Enigma2RemoteKey;
-import org.openhab.core.config.core.Configuration;
-import org.openhab.core.library.types.DecimalType;
-import org.openhab.core.library.types.NextPreviousType;
-import org.openhab.core.library.types.OnOffType;
-import org.openhab.core.library.types.PercentType;
-import org.openhab.core.library.types.PlayPauseType;
-import org.openhab.core.library.types.StringType;
-import org.openhab.core.thing.ChannelUID;
-import org.openhab.core.thing.Thing;
-import org.openhab.core.thing.binding.ThingHandlerCallback;
-import org.openhab.core.types.RefreshType;
-
-/**
- * The {@link Enigma2HandlerTest} class is responsible for testing {@link Enigma2Handler}.
- *
- * @author Guido Dolfen - Initial contribution
- */
-@SuppressWarnings({ "null", "unchecked" })
-@NonNullByDefault
-public class Enigma2HandlerTest {
- public static final String CHANNEL_UID_PREFIX = "enigma2:device:192_168_0_3:";
- public static final String SOME_TEXT = "some Text";
- @Nullable
- private Enigma2Handler enigma2Handler;
- @Nullable
- private Enigma2Client enigma2Client;
- @Nullable
- private Thing thing;
- @Nullable
- private Configuration configuration;
- @Nullable
- private ThingHandlerCallback callback;
-
- @BeforeEach
- public void setUp() {
- enigma2Client = mock(Enigma2Client.class);
- thing = mock(Thing.class);
- callback = mock(ThingHandlerCallback.class);
- configuration = mock(Configuration.class);
- when(thing.getConfiguration()).thenReturn(requireNonNull(configuration));
- when(configuration.as(Enigma2Configuration.class)).thenReturn(new Enigma2Configuration());
- enigma2Handler = spy(new Enigma2Handler(requireNonNull(thing)));
- enigma2Handler.setCallback(callback);
- when(enigma2Handler.getEnigma2Client()).thenReturn(Optional.of(requireNonNull(enigma2Client)));
- }
-
- @Test
- public void testSendRcCommand() {
- enigma2Handler.sendRcCommand("KEY_1");
- verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.KEY_1.getValue());
- }
-
- @Test
- public void testSendInfo() {
- enigma2Handler.sendInfo(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- verify(enigma2Client).sendInfo(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testSendWarning() {
- enigma2Handler.sendWarning(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- verify(enigma2Client).sendWarning(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testSendError() {
- enigma2Handler.sendError(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- verify(enigma2Client).sendError(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testSendQuestion() {
- enigma2Handler.sendQuestion(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- verify(enigma2Client).sendQuestion(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
- }
-
- @Test
- public void testGetEnigma2Client() {
- enigma2Handler = new Enigma2Handler(requireNonNull(thing));
- assertThat(enigma2Handler.getEnigma2Client(), is(Optional.empty()));
- }
-
- @Test
- public void testGetServices() {
- enigma2Handler = new Enigma2Handler(requireNonNull(thing));
- assertThat(enigma2Handler.getServices(), contains(Enigma2Actions.class));
- }
-
- @Test
- public void testSendRcCommandUnsupported() {
- enigma2Handler.sendRcCommand("KEY_X");
- verifyNoInteractions(enigma2Client);
- }
-
- @Test
- public void testHandleCommandPowerRefreshFalse() {
- when(enigma2Client.isPower()).thenReturn(false);
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_POWER);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verify(enigma2Client).refreshPower();
- verify(callback).stateUpdated(channelUID, OnOffType.OFF);
- }
-
- @Test
- public void testHandleCommandPowerRefreshTrue() {
- when(enigma2Client.isPower()).thenReturn(true);
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_POWER);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verify(enigma2Client).refreshPower();
- verify(callback).stateUpdated(channelUID, OnOffType.ON);
- }
-
- @Test
- public void testHandleCommandPowerOn() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_POWER);
- enigma2Handler.handleCommand(channelUID, OnOffType.ON);
- verify(enigma2Client).setPower(true);
- }
-
- @Test
- public void testHandleCommandPowerOff() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_POWER);
- enigma2Handler.handleCommand(channelUID, OnOffType.OFF);
- verify(enigma2Client).setPower(false);
- }
-
- @Test
- public void testHandleCommandPowerUnsupported() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_POWER);
- enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
- verifyNoInteractions(enigma2Client);
- }
-
- @Test
- public void testHandleCommandChannelRefresh() {
- when(enigma2Client.getChannel()).thenReturn(SOME_TEXT);
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_CHANNEL);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verify(enigma2Client).refreshChannel();
- verify(callback).stateUpdated(channelUID, new StringType(SOME_TEXT));
- }
-
- @Test
- public void testHandleCommandMuteRefreshFalse() {
- when(enigma2Client.isMute()).thenReturn(false);
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MUTE);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verify(enigma2Client).refreshVolume();
- verify(callback).stateUpdated(channelUID, OnOffType.OFF);
- }
-
- @Test
- public void testHandleCommandMuteRefreshTrue() {
- when(enigma2Client.isMute()).thenReturn(true);
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MUTE);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verify(enigma2Client).refreshVolume();
- verify(callback).stateUpdated(channelUID, OnOffType.ON);
- }
-
- @Test
- public void testHandleCommandMuteOn() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MUTE);
- enigma2Handler.handleCommand(channelUID, OnOffType.ON);
- verify(enigma2Client).setMute(true);
- }
-
- @Test
- public void testHandleCommandMuteOff() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MUTE);
- enigma2Handler.handleCommand(channelUID, OnOffType.OFF);
- verify(enigma2Client).setMute(false);
- }
-
- @Test
- public void testHandleCommandMuteUnsupported() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MUTE);
- enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
- verifyNoInteractions(enigma2Client);
- }
-
- @Test
- public void testHandleCommandChannelString() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_CHANNEL);
- enigma2Handler.handleCommand(channelUID, new StringType(SOME_TEXT));
- verify(enigma2Client).setChannel(SOME_TEXT);
- }
-
- @Test
- public void testHandleCommandChannelUnsupported() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_CHANNEL);
- enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
- verifyNoInteractions(enigma2Client);
- }
-
- @Test
- public void testHandleCommandMediaPlayerRefresh() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verifyNoInteractions(enigma2Client);
- }
-
- @Test
- public void testHandleCommandMediaPlay() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
- enigma2Handler.handleCommand(channelUID, PlayPauseType.PLAY);
- verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.PLAY.getValue());
- }
-
- @Test
- public void testHandleCommandMediaPause() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
- enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
- verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.PAUSE.getValue());
- }
-
- @Test
- public void testHandleCommandMediaNext() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
- enigma2Handler.handleCommand(channelUID, NextPreviousType.NEXT);
- verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.FAST_FORWARD.getValue());
- }
-
- @Test
- public void testHandleCommandMediaPrevious() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
- enigma2Handler.handleCommand(channelUID, NextPreviousType.PREVIOUS);
- verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.FAST_BACKWARD.getValue());
- }
-
- @Test
- public void testHandleCommandMediaPlayerUnsupported() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
- enigma2Handler.handleCommand(channelUID, OnOffType.ON);
- verifyNoInteractions(enigma2Client);
- }
-
- @Test
- public void testHandleCommandMediaStopRefresh() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_STOP);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verifyNoInteractions(enigma2Client);
- }
-
- @Test
- public void testHandleCommandMediaStopOn() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_STOP);
- enigma2Handler.handleCommand(channelUID, OnOffType.ON);
- verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.STOP.getValue());
- }
-
- @Test
- public void testHandleCommandMediaStopOff() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_STOP);
- enigma2Handler.handleCommand(channelUID, OnOffType.OFF);
- verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.STOP.getValue());
- }
-
- @Test
- public void testHandleCommandMediaStopUnsupported() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_STOP);
- enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
- verifyNoInteractions(enigma2Client);
- }
-
- @Test
- public void testHandleCommandTitleUnsupported() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_TITLE);
- enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
- verifyNoInteractions(enigma2Client);
- }
-
- @Test
- public void testHandleCommandTitleRefresh() {
- when(enigma2Client.getTitle()).thenReturn(SOME_TEXT);
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_TITLE);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verify(enigma2Client).refreshEpg();
- verify(callback).stateUpdated(channelUID, new StringType(SOME_TEXT));
- }
-
- @Test
- public void testHandleCommandAnswerUnsupported() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_ANSWER);
- enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
- verifyNoInteractions(enigma2Client);
- }
-
- @Test
- public void testHandleCommandAnswerRefresh() {
- when(enigma2Client.getAnswer()).thenReturn(SOME_TEXT);
- when(enigma2Client.getLastAnswerTime()).thenReturn(LocalDateTime.now().plus(1, ChronoUnit.SECONDS));
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_ANSWER);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verify(enigma2Client).refreshAnswer();
- verify(callback).stateUpdated(channelUID, new StringType(SOME_TEXT));
- }
-
- @Test
- public void testHandleCommandAnswerRefreshFalse() {
- when(enigma2Client.getAnswer()).thenReturn(SOME_TEXT);
- when(enigma2Client.getLastAnswerTime()).thenReturn(LocalDateTime.of(2020, 1, 1, 0, 0));
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_ANSWER);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verify(enigma2Client).refreshAnswer();
- verifyNoInteractions(callback);
- }
-
- @Test
- public void testHandleCommandDescriptionUnsupported() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_DESCRIPTION);
- enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
- verifyNoInteractions(enigma2Client);
- }
-
- @Test
- public void testHandleCommandDescriptionRefresh() {
- when(enigma2Client.getDescription()).thenReturn(SOME_TEXT);
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_DESCRIPTION);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verify(enigma2Client).refreshEpg();
- verify(callback).stateUpdated(channelUID, new StringType(SOME_TEXT));
- }
-
- @Test
- public void testHandleCommandVolumeRefresh() {
- when(enigma2Client.getVolume()).thenReturn(35);
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_VOLUME);
- enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
- verify(enigma2Client).refreshVolume();
- verify(callback).stateUpdated(channelUID, new PercentType(35));
- }
-
- @Test
- public void testHandleCommandVolumePercent() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_VOLUME);
- enigma2Handler.handleCommand(channelUID, new PercentType(30));
- verify(enigma2Client).setVolume(30);
- }
-
- @Test
- public void testHandleCommandVolumeDecimal() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_VOLUME);
- enigma2Handler.handleCommand(channelUID, new DecimalType(40));
- verify(enigma2Client).setVolume(40);
- }
-
- @Test
- public void testHandleCommandVolumeUnsupported() {
- ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_VOLUME);
- enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
- verifyNoInteractions(enigma2Client);
- }
-}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.enigma2.internal.actions;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.*;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.enigma2.internal.Enigma2BindingConstants;
+import org.openhab.binding.enigma2.internal.handler.Enigma2Handler;
+
+/**
+ * The {@link Enigma2ActionsTest} class is responsible for testing {@link Enigma2Actions}.
+ *
+ * @author Guido Dolfen - Initial contribution
+ */
+@SuppressWarnings("null")
+@NonNullByDefault
+public class Enigma2ActionsTest {
+ @Nullable
+ private Enigma2Actions enigma2Actions;
+ @Nullable
+ private Enigma2Handler enigma2Handler;
+ public static final String SOME_TEXT = "some Text";
+
+ @BeforeEach
+ public void setUp() {
+ enigma2Handler = mock(Enigma2Handler.class);
+ enigma2Actions = new Enigma2Actions();
+ enigma2Actions.setThingHandler(enigma2Handler);
+ }
+
+ @Test
+ public void testGetThingHandler() {
+ assertThat(enigma2Actions.getThingHandler(), is(enigma2Handler));
+ }
+
+ @Test
+ public void testSendRcCommand() {
+ enigma2Actions.sendRcCommand("KEY_1");
+ verify(enigma2Handler).sendRcCommand("KEY_1");
+ }
+
+ @Test
+ public void testSendInfo() {
+ enigma2Actions.sendInfo(SOME_TEXT);
+ verify(enigma2Handler).sendInfo(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendInfoTimeout() {
+ enigma2Actions.sendInfo(SOME_TEXT, 10);
+ verify(enigma2Handler).sendInfo(10, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendError() {
+ enigma2Actions.sendError(SOME_TEXT);
+ verify(enigma2Handler).sendError(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendErrorTimeout() {
+ enigma2Actions.sendError(SOME_TEXT, 10);
+ verify(enigma2Handler).sendError(10, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendWarning() {
+ enigma2Actions.sendWarning(SOME_TEXT);
+ verify(enigma2Handler).sendWarning(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendWarningTimeout() {
+ enigma2Actions.sendWarning(SOME_TEXT, 10);
+ verify(enigma2Handler).sendWarning(10, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendQuestion() {
+ enigma2Actions.sendQuestion(SOME_TEXT);
+ verify(enigma2Handler).sendQuestion(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendQuestionTimeout() {
+ enigma2Actions.sendQuestion(SOME_TEXT, 10);
+ verify(enigma2Handler).sendQuestion(10, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendRcCommandStatic() {
+ Enigma2Actions.sendRcCommand(enigma2Actions, "KEY_1");
+ verify(enigma2Handler).sendRcCommand("KEY_1");
+ }
+
+ @Test
+ public void testSendRcCommandStaticWithException() {
+ assertThrows(IllegalArgumentException.class, () -> Enigma2Actions.sendRcCommand(null, "KEY_1"));
+ }
+
+ @Test
+ public void testSendInfoStatic() {
+ Enigma2Actions.sendInfo(enigma2Actions, SOME_TEXT);
+ verify(enigma2Handler).sendInfo(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendInfoTimeoutStatic() {
+ Enigma2Actions.sendInfo(enigma2Actions, SOME_TEXT, 10);
+ verify(enigma2Handler).sendInfo(10, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendInfoStaticWithException() {
+ assertThrows(IllegalArgumentException.class, () -> Enigma2Actions.sendInfo(null, SOME_TEXT));
+ }
+
+ @Test
+ public void testSendErrorStatic() {
+ Enigma2Actions.sendError(enigma2Actions, SOME_TEXT);
+ verify(enigma2Handler).sendError(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendErrorTimeoutStatic() {
+ Enigma2Actions.sendError(enigma2Actions, SOME_TEXT, 10);
+ verify(enigma2Handler).sendError(10, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendErrorStaticWithException() {
+ assertThrows(IllegalArgumentException.class, () -> Enigma2Actions.sendError(null, SOME_TEXT));
+ }
+
+ @Test
+ public void testSendWarningStatic() {
+ Enigma2Actions.sendWarning(enigma2Actions, SOME_TEXT);
+ verify(enigma2Handler).sendWarning(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendWarningTimeoutStatic() {
+ Enigma2Actions.sendWarning(enigma2Actions, SOME_TEXT, 10);
+ verify(enigma2Handler).sendWarning(10, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendWarningStaticWithException() {
+ assertThrows(IllegalArgumentException.class, () -> Enigma2Actions.sendWarning(null, SOME_TEXT));
+ }
+
+ @Test
+ public void testSendQuestionStatic() {
+ Enigma2Actions.sendQuestion(enigma2Actions, SOME_TEXT);
+ verify(enigma2Handler).sendQuestion(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendQuestionTimeoutStatic() {
+ Enigma2Actions.sendQuestion(enigma2Actions, SOME_TEXT, 10);
+ verify(enigma2Handler).sendQuestion(10, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendQuestionStaticWithException() {
+ assertThrows(IllegalArgumentException.class, () -> Enigma2Actions.sendQuestion(null, SOME_TEXT));
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.enigma2.internal.handler;
+
+import static org.eclipse.jdt.annotation.Checks.requireNonNull;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.Optional;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.enigma2.internal.Enigma2BindingConstants;
+import org.openhab.binding.enigma2.internal.Enigma2Client;
+import org.openhab.binding.enigma2.internal.Enigma2Configuration;
+import org.openhab.binding.enigma2.internal.Enigma2RemoteKey;
+import org.openhab.binding.enigma2.internal.actions.Enigma2Actions;
+import org.openhab.core.config.core.Configuration;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.NextPreviousType;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.PercentType;
+import org.openhab.core.library.types.PlayPauseType;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.binding.ThingHandlerCallback;
+import org.openhab.core.types.RefreshType;
+
+/**
+ * The {@link Enigma2HandlerTest} class is responsible for testing {@link Enigma2Handler}.
+ *
+ * @author Guido Dolfen - Initial contribution
+ */
+@SuppressWarnings({ "null", "unchecked" })
+@NonNullByDefault
+public class Enigma2HandlerTest {
+ public static final String CHANNEL_UID_PREFIX = "enigma2:device:192_168_0_3:";
+ public static final String SOME_TEXT = "some Text";
+ @Nullable
+ private Enigma2Handler enigma2Handler;
+ @Nullable
+ private Enigma2Client enigma2Client;
+ @Nullable
+ private Thing thing;
+ @Nullable
+ private Configuration configuration;
+ @Nullable
+ private ThingHandlerCallback callback;
+
+ @BeforeEach
+ public void setUp() {
+ enigma2Client = mock(Enigma2Client.class);
+ thing = mock(Thing.class);
+ callback = mock(ThingHandlerCallback.class);
+ configuration = mock(Configuration.class);
+ when(thing.getConfiguration()).thenReturn(requireNonNull(configuration));
+ when(configuration.as(Enigma2Configuration.class)).thenReturn(new Enigma2Configuration());
+ enigma2Handler = spy(new Enigma2Handler(requireNonNull(thing)));
+ enigma2Handler.setCallback(callback);
+ when(enigma2Handler.getEnigma2Client()).thenReturn(Optional.of(requireNonNull(enigma2Client)));
+ }
+
+ @Test
+ public void testSendRcCommand() {
+ enigma2Handler.sendRcCommand("KEY_1");
+ verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.KEY_1.getValue());
+ }
+
+ @Test
+ public void testSendInfo() {
+ enigma2Handler.sendInfo(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ verify(enigma2Client).sendInfo(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendWarning() {
+ enigma2Handler.sendWarning(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ verify(enigma2Client).sendWarning(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendError() {
+ enigma2Handler.sendError(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ verify(enigma2Client).sendError(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testSendQuestion() {
+ enigma2Handler.sendQuestion(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ verify(enigma2Client).sendQuestion(Enigma2BindingConstants.MESSAGE_TIMEOUT, SOME_TEXT);
+ }
+
+ @Test
+ public void testGetEnigma2Client() {
+ enigma2Handler = new Enigma2Handler(requireNonNull(thing));
+ assertThat(enigma2Handler.getEnigma2Client(), is(Optional.empty()));
+ }
+
+ @Test
+ public void testGetServices() {
+ enigma2Handler = new Enigma2Handler(requireNonNull(thing));
+ assertThat(enigma2Handler.getServices(), contains(Enigma2Actions.class));
+ }
+
+ @Test
+ public void testSendRcCommandUnsupported() {
+ enigma2Handler.sendRcCommand("KEY_X");
+ verifyNoInteractions(enigma2Client);
+ }
+
+ @Test
+ public void testHandleCommandPowerRefreshFalse() {
+ when(enigma2Client.isPower()).thenReturn(false);
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_POWER);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verify(enigma2Client).refreshPower();
+ verify(callback).stateUpdated(channelUID, OnOffType.OFF);
+ }
+
+ @Test
+ public void testHandleCommandPowerRefreshTrue() {
+ when(enigma2Client.isPower()).thenReturn(true);
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_POWER);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verify(enigma2Client).refreshPower();
+ verify(callback).stateUpdated(channelUID, OnOffType.ON);
+ }
+
+ @Test
+ public void testHandleCommandPowerOn() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_POWER);
+ enigma2Handler.handleCommand(channelUID, OnOffType.ON);
+ verify(enigma2Client).setPower(true);
+ }
+
+ @Test
+ public void testHandleCommandPowerOff() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_POWER);
+ enigma2Handler.handleCommand(channelUID, OnOffType.OFF);
+ verify(enigma2Client).setPower(false);
+ }
+
+ @Test
+ public void testHandleCommandPowerUnsupported() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_POWER);
+ enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
+ verifyNoInteractions(enigma2Client);
+ }
+
+ @Test
+ public void testHandleCommandChannelRefresh() {
+ when(enigma2Client.getChannel()).thenReturn(SOME_TEXT);
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_CHANNEL);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verify(enigma2Client).refreshChannel();
+ verify(callback).stateUpdated(channelUID, new StringType(SOME_TEXT));
+ }
+
+ @Test
+ public void testHandleCommandMuteRefreshFalse() {
+ when(enigma2Client.isMute()).thenReturn(false);
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MUTE);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verify(enigma2Client).refreshVolume();
+ verify(callback).stateUpdated(channelUID, OnOffType.OFF);
+ }
+
+ @Test
+ public void testHandleCommandMuteRefreshTrue() {
+ when(enigma2Client.isMute()).thenReturn(true);
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MUTE);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verify(enigma2Client).refreshVolume();
+ verify(callback).stateUpdated(channelUID, OnOffType.ON);
+ }
+
+ @Test
+ public void testHandleCommandMuteOn() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MUTE);
+ enigma2Handler.handleCommand(channelUID, OnOffType.ON);
+ verify(enigma2Client).setMute(true);
+ }
+
+ @Test
+ public void testHandleCommandMuteOff() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MUTE);
+ enigma2Handler.handleCommand(channelUID, OnOffType.OFF);
+ verify(enigma2Client).setMute(false);
+ }
+
+ @Test
+ public void testHandleCommandMuteUnsupported() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MUTE);
+ enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
+ verifyNoInteractions(enigma2Client);
+ }
+
+ @Test
+ public void testHandleCommandChannelString() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_CHANNEL);
+ enigma2Handler.handleCommand(channelUID, new StringType(SOME_TEXT));
+ verify(enigma2Client).setChannel(SOME_TEXT);
+ }
+
+ @Test
+ public void testHandleCommandChannelUnsupported() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_CHANNEL);
+ enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
+ verifyNoInteractions(enigma2Client);
+ }
+
+ @Test
+ public void testHandleCommandMediaPlayerRefresh() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verifyNoInteractions(enigma2Client);
+ }
+
+ @Test
+ public void testHandleCommandMediaPlay() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
+ enigma2Handler.handleCommand(channelUID, PlayPauseType.PLAY);
+ verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.PLAY.getValue());
+ }
+
+ @Test
+ public void testHandleCommandMediaPause() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
+ enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
+ verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.PAUSE.getValue());
+ }
+
+ @Test
+ public void testHandleCommandMediaNext() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
+ enigma2Handler.handleCommand(channelUID, NextPreviousType.NEXT);
+ verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.FAST_FORWARD.getValue());
+ }
+
+ @Test
+ public void testHandleCommandMediaPrevious() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
+ enigma2Handler.handleCommand(channelUID, NextPreviousType.PREVIOUS);
+ verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.FAST_BACKWARD.getValue());
+ }
+
+ @Test
+ public void testHandleCommandMediaPlayerUnsupported() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_PLAYER);
+ enigma2Handler.handleCommand(channelUID, OnOffType.ON);
+ verifyNoInteractions(enigma2Client);
+ }
+
+ @Test
+ public void testHandleCommandMediaStopRefresh() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_STOP);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verifyNoInteractions(enigma2Client);
+ }
+
+ @Test
+ public void testHandleCommandMediaStopOn() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_STOP);
+ enigma2Handler.handleCommand(channelUID, OnOffType.ON);
+ verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.STOP.getValue());
+ }
+
+ @Test
+ public void testHandleCommandMediaStopOff() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_STOP);
+ enigma2Handler.handleCommand(channelUID, OnOffType.OFF);
+ verify(enigma2Client).sendRcCommand(Enigma2RemoteKey.STOP.getValue());
+ }
+
+ @Test
+ public void testHandleCommandMediaStopUnsupported() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_MEDIA_STOP);
+ enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
+ verifyNoInteractions(enigma2Client);
+ }
+
+ @Test
+ public void testHandleCommandTitleUnsupported() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_TITLE);
+ enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
+ verifyNoInteractions(enigma2Client);
+ }
+
+ @Test
+ public void testHandleCommandTitleRefresh() {
+ when(enigma2Client.getTitle()).thenReturn(SOME_TEXT);
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_TITLE);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verify(enigma2Client).refreshEpg();
+ verify(callback).stateUpdated(channelUID, new StringType(SOME_TEXT));
+ }
+
+ @Test
+ public void testHandleCommandAnswerUnsupported() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_ANSWER);
+ enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
+ verifyNoInteractions(enigma2Client);
+ }
+
+ @Test
+ public void testHandleCommandAnswerRefresh() {
+ when(enigma2Client.getAnswer()).thenReturn(SOME_TEXT);
+ when(enigma2Client.getLastAnswerTime()).thenReturn(LocalDateTime.now().plus(1, ChronoUnit.SECONDS));
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_ANSWER);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verify(enigma2Client).refreshAnswer();
+ verify(callback).stateUpdated(channelUID, new StringType(SOME_TEXT));
+ }
+
+ @Test
+ public void testHandleCommandAnswerRefreshFalse() {
+ when(enigma2Client.getAnswer()).thenReturn(SOME_TEXT);
+ when(enigma2Client.getLastAnswerTime()).thenReturn(LocalDateTime.of(2020, 1, 1, 0, 0));
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_ANSWER);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verify(enigma2Client).refreshAnswer();
+ verifyNoInteractions(callback);
+ }
+
+ @Test
+ public void testHandleCommandDescriptionUnsupported() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_DESCRIPTION);
+ enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
+ verifyNoInteractions(enigma2Client);
+ }
+
+ @Test
+ public void testHandleCommandDescriptionRefresh() {
+ when(enigma2Client.getDescription()).thenReturn(SOME_TEXT);
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_DESCRIPTION);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verify(enigma2Client).refreshEpg();
+ verify(callback).stateUpdated(channelUID, new StringType(SOME_TEXT));
+ }
+
+ @Test
+ public void testHandleCommandVolumeRefresh() {
+ when(enigma2Client.getVolume()).thenReturn(35);
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_VOLUME);
+ enigma2Handler.handleCommand(channelUID, RefreshType.REFRESH);
+ verify(enigma2Client).refreshVolume();
+ verify(callback).stateUpdated(channelUID, new PercentType(35));
+ }
+
+ @Test
+ public void testHandleCommandVolumePercent() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_VOLUME);
+ enigma2Handler.handleCommand(channelUID, new PercentType(30));
+ verify(enigma2Client).setVolume(30);
+ }
+
+ @Test
+ public void testHandleCommandVolumeDecimal() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_VOLUME);
+ enigma2Handler.handleCommand(channelUID, new DecimalType(40));
+ verify(enigma2Client).setVolume(40);
+ }
+
+ @Test
+ public void testHandleCommandVolumeUnsupported() {
+ ChannelUID channelUID = new ChannelUID(CHANNEL_UID_PREFIX + Enigma2BindingConstants.CHANNEL_VOLUME);
+ enigma2Handler.handleCommand(channelUID, PlayPauseType.PAUSE);
+ verifyNoInteractions(enigma2Client);
+ }
+}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.gce.internal.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link IIpx800Actions} defines the interface for all thing actions supported by the binding.
- *
- * @author Gaël L'hopital - Initial contribution
- */
-@NonNullByDefault
-public interface IIpx800Actions {
- public void resetCounter(Integer counter);
-
- public void reset(@Nullable Integer placeholder);
-}
*/
package org.openhab.binding.gce.internal.action;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.gce.internal.handler.Ipx800v3Handler;
import org.slf4j.LoggerFactory;
/**
- * The {Ipx800Actions } defines rule actions for the GCE binding.
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof Ipx800Actions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link Ipx800Actions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
+ * Defines rule actions for the GCE binding.
*
* @author Gaël L'hopital - Initial contribution
*/
@ThingActionsScope(name = "gce")
@NonNullByDefault
-public class Ipx800Actions implements ThingActions, IIpx800Actions {
+public class Ipx800Actions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(Ipx800Actions.class);
protected @Nullable Ipx800v3Handler handler;
@Override
public @Nullable ThingHandler getThingHandler() {
- return this.handler;
+ return handler;
}
- @Override
- @RuleAction(label = "GCE : Reset counter", description = "Resets to 0 value of a given counter")
+ @RuleAction(label = "reset a counter", description = "Resets to 0 value of a given counter.")
public void resetCounter(
@ActionInput(name = "counter", label = "Counter", required = true, description = "Id of the counter", type = "java.lang.Integer") Integer counter) {
logger.debug("IPX800 action 'resetCounter' called");
}
}
- @Override
- @RuleAction(label = "GCE : Reset PLC", description = "Restarts the IPX800")
+ @RuleAction(label = "reset the PLC", description = "Restarts the IPX800.")
public void reset(
@ActionInput(name = "placeholder", label = "Placeholder", required = false, description = "This parameter is not used", type = "java.lang.Integer") @Nullable Integer placeholder) {
logger.debug("IPX800 action 'reset' called");
}
public static void resetCounter(@Nullable ThingActions actions, Integer counter) {
- invokeMethodOf(actions).resetCounter(counter);
+ if (actions instanceof Ipx800Actions) {
+ ((Ipx800Actions) actions).resetCounter(counter);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of Ipx800Actions");
+ }
}
public static void reset(@Nullable ThingActions actions, @Nullable Integer placeholder) {
- invokeMethodOf(actions).reset(placeholder);
- }
-
- private static IIpx800Actions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(Ipx800Actions.class.getName())) {
- if (actions instanceof IIpx800Actions) {
- return (IIpx800Actions) actions;
- } else {
- return (IIpx800Actions) Proxy.newProxyInstance(IIpx800Actions.class.getClassLoader(),
- new Class[] { IIpx800Actions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
+ if (actions instanceof Ipx800Actions) {
+ ((Ipx800Actions) actions).reset(placeholder);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of Ipx800Actions");
}
- throw new IllegalArgumentException("Actions is not an instance of Ipx800Actions");
}
}
package org.openhab.binding.heos.internal.action;
import java.io.IOException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/**
* The class is responsible to call corresponding action on HEOS Handler
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof HeosActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link HeosActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
*
* @author Martin van Wingerden - Initial contribution
*/
@ThingActionsScope(name = "heos")
@NonNullByDefault
-public class HeosActions implements ThingActions, IHeosActions {
+public class HeosActions implements ThingActions {
private final static Logger logger = LoggerFactory.getLogger(HeosActions.class);
@Override
public @Nullable ThingHandler getThingHandler() {
- return this.handler;
+ return handler;
}
private @Nullable HeosFacade getConnection() throws HeosNotConnectedException {
+ HeosBridgeHandler handler = this.handler;
if (handler == null) {
return null;
}
return handler.getApiConnection();
}
- @Override
@RuleAction(label = "Play Input", description = "Play an input from another device")
public void playInputFromPlayer(
@ActionInput(name = "source", label = "Source Player", description = "Player used for input") @Nullable Integer sourcePlayer,
public static void playInputFromPlayer(@Nullable ThingActions actions, @Nullable Integer sourcePlayer,
@Nullable String input, @Nullable Integer destinationPlayer) {
- invokeMethodOf(actions).playInputFromPlayer(sourcePlayer, input, destinationPlayer);
- }
-
- private static IHeosActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(HeosActions.class.getName())) {
- if (actions instanceof IHeosActions) {
- return (IHeosActions) actions;
- } else {
- return (IHeosActions) Proxy.newProxyInstance(IHeosActions.class.getClassLoader(),
- new Class[] { IHeosActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
+ if (actions instanceof HeosActions) {
+ ((HeosActions) actions).playInputFromPlayer(sourcePlayer, input, destinationPlayer);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of HeosActions");
}
- throw new IllegalArgumentException("Actions is not an instance of HeosActions");
}
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.heos.internal.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link IHeosActions} defines the interface for all thing actions supported by the binding.
- *
- * @author Laurent Garnier - Initial contribution
- */
-@NonNullByDefault
-public interface IHeosActions {
-
- public void playInputFromPlayer(@Nullable Integer sourcePlayer, @Nullable String input,
- @Nullable Integer destinationPlayer);
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.hue.internal.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.library.types.DecimalType;
-import org.openhab.core.types.Command;
-
-/**
- * The {@link ILightActions} defines the interface for all thing actions supported by the binding.
- *
- * @author Laurent Garnier - Initial contribution
- */
-@NonNullByDefault
-public interface ILightActions {
-
- public void fadingLightCommand(@Nullable String channel, @Nullable Command command, @Nullable DecimalType fadeTime);
-}
*/
package org.openhab.binding.hue.internal.action;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.hue.internal.handler.HueLightHandler;
/**
* The {@link LightActions} defines the thing actions for the hue binding.
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof LightActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link LightActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
*
* @author Jochen Leopold - Initial contribution
* @author Laurent Garnier - new method invokeMethodOf + interface ILightActions
*/
@ThingActionsScope(name = "hue")
@NonNullByDefault
-public class LightActions implements ThingActions, ILightActions {
+public class LightActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(LightActions.class);
private @Nullable HueLightHandler handler;
@Override
public @Nullable ThingHandler getThingHandler() {
- return this.handler;
+ return handler;
}
- @Override
@RuleAction(label = "@text/actionLabel", description = "@text/actionDesc")
public void fadingLightCommand(
@ActionInput(name = "channel", label = "@text/actionInputChannelLabel", description = "@text/actionInputChannelDesc") @Nullable String channel,
logger.debug("send LightAction to {} with {}ms of fadeTime", channel, fadeTime);
}
- private static ILightActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(LightActions.class.getName())) {
- if (actions instanceof ILightActions) {
- return (ILightActions) actions;
- } else {
- return (ILightActions) Proxy.newProxyInstance(ILightActions.class.getClassLoader(),
- new Class[] { ILightActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of LightActions");
- }
-
public static void fadingLightCommand(@Nullable ThingActions actions, @Nullable String channel,
@Nullable Command command, @Nullable DecimalType fadeTime) {
- invokeMethodOf(actions).fadingLightCommand(channel, command, fadeTime);
+ if (actions instanceof LightActions) {
+ ((LightActions) actions).fadingLightCommand(channel, command, fadeTime);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LightActions");
+ }
}
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.kaleidescape.internal;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * The {@link IKaleidescapeThingActions} defines the interface for all thing actions supported by the binding.
- * These methods, parameters, and return types are explained in {@link KaleidescapeThingActions}.
- *
- * @author Michael Lobstein - Initial contribution
- */
-@NonNullByDefault
-public interface IKaleidescapeThingActions {
-
- void sendKCommand(String kCommand);
-}
*/
package org.openhab.binding.kaleidescape.internal;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.kaleidescape.internal.handler.KaleidescapeHandler;
* Some automation actions to be used with a {@link KaleidescapeThingActions}
*
* @author Michael Lobstein - initial contribution
- *
*/
@ThingActionsScope(name = "kaleidescape")
@NonNullByDefault
-public class KaleidescapeThingActions implements ThingActions, IKaleidescapeThingActions {
+public class KaleidescapeThingActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(KaleidescapeThingActions.class);
private @Nullable KaleidescapeHandler handler;
- @RuleAction(label = "sendKCommand", description = "Action that sends raw command to the kaleidescape zone")
+ @RuleAction(label = "send a raw command", description = "Action that sends raw command to the kaleidescape zone.")
public void sendKCommand(@ActionInput(name = "sendKCommand") String kCommand) {
KaleidescapeHandler localHandler = handler;
if (localHandler != null) {
/** Static alias to support the old DSL rules engine and make the action available there. */
public static void sendKCommand(@Nullable ThingActions actions, String kCommand) throws IllegalArgumentException {
- invokeMethodOf(actions).sendKCommand(kCommand);
+ if (actions instanceof KaleidescapeThingActions) {
+ ((KaleidescapeThingActions) actions).sendKCommand(kCommand);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of KaleidescapeThingActions");
+ }
}
@Override
@Override
public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- private static IKaleidescapeThingActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(KaleidescapeThingActions.class.getName())) {
- if (actions instanceof KaleidescapeThingActions) {
- return (IKaleidescapeThingActions) actions;
- } else {
- return (IKaleidescapeThingActions) Proxy.newProxyInstance(
- IKaleidescapeThingActions.class.getClassLoader(),
- new Class[] { IKaleidescapeThingActions.class },
- (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of KaleidescapeThingActions");
+ return handler;
}
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.lcn.internal;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link ILcnModuleActions} defines the interface for all thing actions supported by the binding.
- * These methods, parameters, and return types are explained in {@link LcnModuleActions}.
- *
- * @author Fabian Wolter - Initial contribution
- */
-@NonNullByDefault
-public interface ILcnModuleActions {
- void hitKey(@Nullable String table, int key, @Nullable String action);
-
- void flickerOutput(int output, int depth, int ramp, int count);
-
- void sendDynamicText(int row, @Nullable String textInput);
-
- void startRelayTimer(int relaynumber, double duration);
-}
*/
package org.openhab.binding.lcn.internal;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
import java.nio.ByteBuffer;
import java.util.Arrays;
*/
@ThingActionsScope(name = "lcn")
@NonNullByDefault
-public class LcnModuleActions implements ThingActions, ILcnModuleActions {
+public class LcnModuleActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(LcnModuleActions.class);
private static final int DYN_TEXT_CHUNK_COUNT = 5;
private static final int DYN_TEXT_HEADER_LENGTH = 6;
return moduleHandler;
}
- @Override
- @RuleAction(label = "LCN Hit Key", description = "Sends a \"hit key\" command to an LCN module")
+ @RuleAction(label = "send a hit key command", description = "Sends a \"hit key\" command to an LCN module.")
public void hitKey(
@ActionInput(name = "table", required = true, type = "java.lang.String", label = "Table", description = "The key table (A-D)") @Nullable String table,
@ActionInput(name = "key", required = true, type = "java.lang.Integer", label = "Key", description = "The key number (1-8)") int key,
}
}
- @Override
- @RuleAction(label = "LCN Flicker Output", description = "Let a dimmer output flicker for a given count of flashes")
+ @RuleAction(label = "flicker a dimmer output", description = "Let a dimmer output flicker for a given count of flashes.")
public void flickerOutput(
@ActionInput(name = "output", type = "java.lang.Integer", required = true, label = "Output", description = "The output number (1-4)") int output,
@ActionInput(name = "depth", type = "java.lang.Integer", label = "Depth", description = "0=25% 1=50% 2=100%") int depth,
}
}
- @Override
- @RuleAction(label = "LCN Dynamic Text", description = "Send custom text to an LCN-GTxD display")
+ @RuleAction(label = "send a custom text", description = "Send custom text to an LCN-GTxD display.")
public void sendDynamicText(
@ActionInput(name = "row", type = "java.lang.Integer", required = true, label = "Row", description = "Display the text on the LCN-GTxD in the given row number (1-4)") int row,
@ActionInput(name = "text", type = "java.lang.String", label = "Text", description = "The text to display (max. 60 chars/bytes)") @Nullable String textInput) {
* @param relaynumber 1-based number of the relay to use
* @param duration duration of the relay timer in milliseconds
*/
- @Override
- @RuleAction(label = "LCN Relay Timer", description = "Start an LCN relay timer")
+ @RuleAction(label = "start a relay timer", description = "Start an LCN relay timer.")
public void startRelayTimer(
@ActionInput(name = "relaynumber", required = true, type = "java.lang.Integer", label = "Relay Number", description = "The relay number (1-8)") int relayNumber,
@ActionInput(name = "duration", required = true, type = "java.lang.Double", label = "Duration [ms]", description = "The timer duration in milliseconds") double duration) {
}
}
- private static ILcnModuleActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(LcnModuleActions.class.getName())) {
- if (actions instanceof LcnModuleActions) {
- return (ILcnModuleActions) actions;
- } else {
- return (ILcnModuleActions) Proxy.newProxyInstance(ILcnModuleActions.class.getClassLoader(),
- new Class[] { ILcnModuleActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of LcnModuleActions");
- }
-
/** Static alias to support the old DSL rules engine and make the action available there. */
public static void hitKey(@Nullable ThingActions actions, @Nullable String table, int key,
@Nullable String action) {
- invokeMethodOf(actions).hitKey(table, key, action);
+ if (actions instanceof LcnModuleHandler) {
+ ((LcnModuleActions) actions).hitKey(table, key, action);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LcnModuleActions");
+ }
}
/** Static alias to support the old DSL rules engine and make the action available there. */
public static void flickerOutput(@Nullable ThingActions actions, int output, int depth, int ramp, int count) {
- invokeMethodOf(actions).flickerOutput(output, depth, ramp, count);
+ if (actions instanceof LcnModuleHandler) {
+ ((LcnModuleActions) actions).flickerOutput(output, depth, ramp, count);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LcnModuleActions");
+ }
}
/** Static alias to support the old DSL rules engine and make the action available there. */
public static void sendDynamicText(@Nullable ThingActions actions, int row, @Nullable String text) {
- invokeMethodOf(actions).sendDynamicText(row, text);
+ if (actions instanceof LcnModuleHandler) {
+ ((LcnModuleActions) actions).sendDynamicText(row, text);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LcnModuleActions");
+ }
}
/** Static alias to support the old DSL rules engine and make the action available there. */
public static void startRelayTimer(@Nullable ThingActions actions, int relaynumber, double duration) {
- invokeMethodOf(actions).startRelayTimer(relaynumber, duration);
+ if (actions instanceof LcnModuleHandler) {
+ ((LcnModuleActions) actions).startRelayTimer(relaynumber, duration);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LcnModuleActions");
+ }
}
private LcnModuleHandler getHandler() throws LcnException {
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.lgwebos.action;
-
-import java.io.IOException;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * The {@link ILGWebOSActions} defines the interface for all thing actions supported by the binding.
- *
- * @author Laurent Garnier - Initial contribution
- */
-@NonNullByDefault
-public interface ILGWebOSActions {
-
- public void showToast(String text) throws IOException;
-
- public void showToast(String icon, String text) throws IOException;
-
- public void launchBrowser(String url);
-
- public void launchApplication(String appId);
-
- public void launchApplication(String appId, String params);
-
- public void sendText(String text);
-
- public void sendButton(String button);
-
- public void increaseChannel();
-
- public void decreaseChannel();
-
- public void sendRCButton(String rcButton);
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.lgwebos.action;
-
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import javax.imageio.ImageIO;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.lgwebos.internal.handler.LGWebOSHandler;
-import org.openhab.binding.lgwebos.internal.handler.LGWebOSTVMouseSocket.ButtonType;
-import org.openhab.binding.lgwebos.internal.handler.LGWebOSTVSocket;
-import org.openhab.binding.lgwebos.internal.handler.LGWebOSTVSocket.State;
-import org.openhab.binding.lgwebos.internal.handler.command.ServiceSubscription;
-import org.openhab.binding.lgwebos.internal.handler.core.AppInfo;
-import org.openhab.binding.lgwebos.internal.handler.core.ResponseListener;
-import org.openhab.binding.lgwebos.internal.handler.core.TextInputStatusInfo;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonParser;
-
-/**
- * The {@link LGWebOSActions} defines the thing actions for the LGwebOS binding.
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof LGWebOSActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link LGWebOSActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
- *
- * @author Sebastian Prehn - Initial contribution
- * @author Laurent Garnier - new method invokeMethodOf + interface ILGWebOSActions
- */
-@ThingActionsScope(name = "lgwebos")
-@NonNullByDefault
-public class LGWebOSActions implements ThingActions, ILGWebOSActions {
- private final Logger logger = LoggerFactory.getLogger(LGWebOSActions.class);
- private final ResponseListener<TextInputStatusInfo> textInputListener = createTextInputStatusListener();
- private @Nullable LGWebOSHandler handler;
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- this.handler = (LGWebOSHandler) handler;
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- // a NonNull getter for handler
- private LGWebOSHandler getLGWebOSHandler() {
- LGWebOSHandler lgWebOSHandler = this.handler;
- if (lgWebOSHandler == null) {
- throw new IllegalStateException(
- "ThingHandler must be set before any action may be invoked on LGWebOSActions.");
- }
- return lgWebOSHandler;
- }
-
- private enum Button {
- UP,
- DOWN,
- LEFT,
- RIGHT,
- BACK,
- DELETE,
- ENTER,
- HOME,
- OK
- }
-
- @Override
- @RuleAction(label = "@text/actionShowToastLabel", description = "@text/actionShowToastDesc")
- public void showToast(
- @ActionInput(name = "text", label = "@text/actionShowToastInputTextLabel", description = "@text/actionShowToastInputTextDesc") String text)
- throws IOException {
- getConnectedSocket().ifPresent(control -> control.showToast(text, createResponseListener()));
- }
-
- @Override
- @RuleAction(label = "@text/actionShowToastWithIconLabel", description = "@text/actionShowToastWithIconLabel")
- public void showToast(
- @ActionInput(name = "icon", label = "@text/actionShowToastInputIconLabel", description = "@text/actionShowToastInputIconDesc") String icon,
- @ActionInput(name = "text", label = "@text/actionShowToastInputTextLabel", description = "@text/actionShowToastInputTextDesc") String text)
- throws IOException {
- BufferedImage bi = ImageIO.read(new URL(icon));
- try (ByteArrayOutputStream os = new ByteArrayOutputStream(); OutputStream b64 = Base64.getEncoder().wrap(os)) {
- ImageIO.write(bi, "png", b64);
- String string = os.toString(StandardCharsets.UTF_8.name());
- getConnectedSocket().ifPresent(control -> control.showToast(text, string, "png", createResponseListener()));
- }
- }
-
- @Override
- @RuleAction(label = "@text/actionLaunchBrowserLabel", description = "@text/actionLaunchBrowserDesc")
- public void launchBrowser(
- @ActionInput(name = "url", label = "@text/actionLaunchBrowserInputUrlLabel", description = "@text/actionLaunchBrowserInputUrlDesc") String url) {
- getConnectedSocket().ifPresent(control -> control.launchBrowser(url, createResponseListener()));
- }
-
- private List<AppInfo> getAppInfos() {
- LGWebOSHandler lgWebOSHandler = getLGWebOSHandler();
-
- if (!this.getConnectedSocket().isPresent()) {
- return Collections.emptyList();
- }
-
- List<AppInfo> appInfos = lgWebOSHandler.getLauncherApplication()
- .getAppInfos(lgWebOSHandler.getThing().getUID());
- if (appInfos == null) {
- logger.warn("No AppInfos found for device with ThingID {}.", lgWebOSHandler.getThing().getUID());
- return Collections.emptyList();
- }
- return appInfos;
- }
-
- @Override
- @RuleAction(label = "@text/actionLaunchApplicationLabel", description = "@text/actionLaunchApplicationDesc")
- public void launchApplication(
- @ActionInput(name = "appId", label = "@text/actionLaunchApplicationInputAppIDLabel", description = "@text/actionLaunchApplicationInputAppIDDesc") String appId) {
- Optional<AppInfo> appInfo = getAppInfos().stream().filter(a -> a.getId().equals(appId)).findFirst();
- if (appInfo.isPresent()) {
- getConnectedSocket()
- .ifPresent(control -> control.launchAppWithInfo(appInfo.get(), createResponseListener()));
- } else {
- logger.warn("Device with ThingID {} does not support any app with id: {}.",
- getLGWebOSHandler().getThing().getUID(), appId);
- }
- }
-
- @Override
- @RuleAction(label = "@text/actionLaunchApplicationWithParamsLabel", description = "@text/actionLaunchApplicationWithParamsDesc")
- public void launchApplication(
- @ActionInput(name = "appId", label = "@text/actionLaunchApplicationInputAppIDLabel", description = "@text/actionLaunchApplicationInputAppIDDesc") String appId,
- @ActionInput(name = "params", label = "@text/actionLaunchApplicationInputParamsLabel", description = "@text/actionLaunchApplicationInputParamsDesc") String params) {
- try {
- JsonParser parser = new JsonParser();
- JsonObject payload = (JsonObject) parser.parse(params);
-
- Optional<AppInfo> appInfo = getAppInfos().stream().filter(a -> a.getId().equals(appId)).findFirst();
- if (appInfo.isPresent()) {
- getConnectedSocket().ifPresent(
- control -> control.launchAppWithInfo(appInfo.get(), payload, createResponseListener()));
- } else {
- logger.warn("Device with ThingID {} does not support any app with id: {}.",
- getLGWebOSHandler().getThing().getUID(), appId);
- }
-
- } catch (JsonParseException ex) {
- logger.warn("Parameters value ({}) is not in a valid JSON format. {}", params, ex.getMessage());
- return;
- }
- }
-
- @Override
- @RuleAction(label = "@text/actionSendTextLabel", description = "@text/actionSendTextDesc")
- public void sendText(
- @ActionInput(name = "text", label = "@text/actionSendTextInputTextLabel", description = "@text/actionSendTextInputTextDesc") String text) {
- getConnectedSocket().ifPresent(control -> {
- ServiceSubscription<TextInputStatusInfo> subscription = control.subscribeTextInputStatus(textInputListener);
- control.sendText(text);
- control.unsubscribe(subscription);
- });
- }
-
- @Override
- @RuleAction(label = "@text/actionSendButtonLabel", description = "@text/actionSendButtonDesc")
- public void sendButton(
- @ActionInput(name = "text", label = "@text/actionSendButtonInputButtonLabel", description = "@text/actionSendButtonInputButtonDesc") String button) {
- try {
- switch (Button.valueOf(button)) {
- case UP:
- getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(ButtonType.UP)));
- break;
- case DOWN:
- getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(ButtonType.DOWN)));
- break;
- case LEFT:
- getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(ButtonType.LEFT)));
- break;
- case RIGHT:
- getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(ButtonType.RIGHT)));
- break;
- case BACK:
- getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(ButtonType.BACK)));
- break;
- case DELETE:
- getConnectedSocket().ifPresent(control -> control.sendDelete());
- break;
- case ENTER:
- getConnectedSocket().ifPresent(control -> control.sendEnter());
- break;
- case HOME:
- getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button("HOME")));
- break;
- case OK:
- getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.click()));
- break;
- }
- } catch (IllegalArgumentException ex) {
- logger.warn("{} is not a valid value for button - available are: {}", button,
- Stream.of(Button.values()).map(b -> b.name()).collect(Collectors.joining(", ")));
- }
- }
-
- @Override
- @RuleAction(label = "@text/actionIncreaseChannelLabel", description = "@text/actionIncreaseChannelDesc")
- public void increaseChannel() {
- getConnectedSocket().ifPresent(control -> control.channelUp(createResponseListener()));
- }
-
- @Override
- @RuleAction(label = "@text/actionDecreaseChannelLabel", description = "@text/actionDecreaseChannelDesc")
- public void decreaseChannel() {
- getConnectedSocket().ifPresent(control -> control.channelDown(createResponseListener()));
- }
-
- @Override
- @RuleAction(label = "@text/actionSendRCButtonLabel", description = "@text/actionSendRCButtonDesc")
- public void sendRCButton(
- @ActionInput(name = "text", label = "@text/actionSendRCButtonInputTextLabel", description = "@text/actionSendRCButtonInputTextDesc") String rcButton) {
- getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(rcButton)));
- }
-
- private Optional<LGWebOSTVSocket> getConnectedSocket() {
- LGWebOSHandler lgWebOSHandler = getLGWebOSHandler();
- final LGWebOSTVSocket socket = lgWebOSHandler.getSocket();
-
- if (socket.getState() != State.REGISTERED) {
- logger.warn("Device with ThingID {} is currently not connected.", lgWebOSHandler.getThing().getUID());
- return Optional.empty();
- }
-
- return Optional.of(socket);
- }
-
- private ResponseListener<TextInputStatusInfo> createTextInputStatusListener() {
- return new ResponseListener<TextInputStatusInfo>() {
-
- @Override
- public void onError(@Nullable String error) {
- logger.warn("Response: {}", error);
- }
-
- @Override
- public void onSuccess(@Nullable TextInputStatusInfo info) {
- logger.debug("Response: {}", info == null ? "OK" : info.getRawData());
- }
- };
- }
-
- private <O> ResponseListener<O> createResponseListener() {
- return new ResponseListener<O>() {
-
- @Override
- public void onError(@Nullable String error) {
- logger.warn("Response: {}", error);
- }
-
- @Override
- public void onSuccess(@Nullable O object) {
- logger.debug("Response: {}", object == null ? "OK" : object.toString());
- }
- };
- }
-
- // delegation methods for "legacy" rule support
-
- private static ILGWebOSActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(LGWebOSActions.class.getName())) {
- if (actions instanceof ILGWebOSActions) {
- return (ILGWebOSActions) actions;
- } else {
- return (ILGWebOSActions) Proxy.newProxyInstance(ILGWebOSActions.class.getClassLoader(),
- new Class[] { ILGWebOSActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of LGWebOSActions");
- }
-
- public static void showToast(@Nullable ThingActions actions, String text) throws IOException {
- invokeMethodOf(actions).showToast(text);
- }
-
- public static void showToast(@Nullable ThingActions actions, String icon, String text) throws IOException {
- invokeMethodOf(actions).showToast(icon, text);
- }
-
- public static void launchBrowser(@Nullable ThingActions actions, String url) {
- invokeMethodOf(actions).launchBrowser(url);
- }
-
- public static void launchApplication(@Nullable ThingActions actions, String appId) {
- invokeMethodOf(actions).launchApplication(appId);
- }
-
- public static void launchApplication(@Nullable ThingActions actions, String appId, String param) {
- invokeMethodOf(actions).launchApplication(appId, param);
- }
-
- public static void sendText(@Nullable ThingActions actions, String text) {
- invokeMethodOf(actions).sendText(text);
- }
-
- public static void sendButton(@Nullable ThingActions actions, String button) {
- invokeMethodOf(actions).sendButton(button);
- }
-
- public static void increaseChannel(@Nullable ThingActions actions) {
- invokeMethodOf(actions).increaseChannel();
- }
-
- public static void decreaseChannel(@Nullable ThingActions actions) {
- invokeMethodOf(actions).decreaseChannel();
- }
-
- public static void sendRCButton(@Nullable ThingActions actions, String rcButton) {
- invokeMethodOf(actions).sendRCButton(rcButton);
- }
-}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.lgwebos.internal.action;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.imageio.ImageIO;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.lgwebos.internal.handler.LGWebOSHandler;
+import org.openhab.binding.lgwebos.internal.handler.LGWebOSTVMouseSocket.ButtonType;
+import org.openhab.binding.lgwebos.internal.handler.LGWebOSTVSocket;
+import org.openhab.binding.lgwebos.internal.handler.LGWebOSTVSocket.State;
+import org.openhab.binding.lgwebos.internal.handler.command.ServiceSubscription;
+import org.openhab.binding.lgwebos.internal.handler.core.AppInfo;
+import org.openhab.binding.lgwebos.internal.handler.core.ResponseListener;
+import org.openhab.binding.lgwebos.internal.handler.core.TextInputStatusInfo;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonParser;
+
+/**
+ * The {@link LGWebOSActions} defines the thing actions for the LGwebOS binding.
+ *
+ * @author Sebastian Prehn - Initial contribution
+ * @author Laurent Garnier - new method invokeMethodOf + interface ILGWebOSActions
+ */
+@ThingActionsScope(name = "lgwebos")
+@NonNullByDefault
+public class LGWebOSActions implements ThingActions {
+ private final Logger logger = LoggerFactory.getLogger(LGWebOSActions.class);
+ private final ResponseListener<TextInputStatusInfo> textInputListener = createTextInputStatusListener();
+ private @Nullable LGWebOSHandler handler;
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ this.handler = (LGWebOSHandler) handler;
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+
+ // a NonNull getter for handler
+ private LGWebOSHandler getLGWebOSHandler() {
+ LGWebOSHandler lgWebOSHandler = this.handler;
+ if (lgWebOSHandler == null) {
+ throw new IllegalStateException(
+ "ThingHandler must be set before any action may be invoked on LGWebOSActions.");
+ }
+ return lgWebOSHandler;
+ }
+
+ private enum Button {
+ UP,
+ DOWN,
+ LEFT,
+ RIGHT,
+ BACK,
+ DELETE,
+ ENTER,
+ HOME,
+ OK
+ }
+
+ @RuleAction(label = "@text/actionShowToastLabel", description = "@text/actionShowToastDesc")
+ public void showToast(
+ @ActionInput(name = "text", label = "@text/actionShowToastInputTextLabel", description = "@text/actionShowToastInputTextDesc") String text)
+ throws IOException {
+ getConnectedSocket().ifPresent(control -> control.showToast(text, createResponseListener()));
+ }
+
+ @RuleAction(label = "@text/actionShowToastWithIconLabel", description = "@text/actionShowToastWithIconLabel")
+ public void showToast(
+ @ActionInput(name = "icon", label = "@text/actionShowToastInputIconLabel", description = "@text/actionShowToastInputIconDesc") String icon,
+ @ActionInput(name = "text", label = "@text/actionShowToastInputTextLabel", description = "@text/actionShowToastInputTextDesc") String text)
+ throws IOException {
+ BufferedImage bi = ImageIO.read(new URL(icon));
+ try (ByteArrayOutputStream os = new ByteArrayOutputStream(); OutputStream b64 = Base64.getEncoder().wrap(os)) {
+ ImageIO.write(bi, "png", b64);
+ String string = os.toString(StandardCharsets.UTF_8.name());
+ getConnectedSocket().ifPresent(control -> control.showToast(text, string, "png", createResponseListener()));
+ }
+ }
+
+ @RuleAction(label = "@text/actionLaunchBrowserLabel", description = "@text/actionLaunchBrowserDesc")
+ public void launchBrowser(
+ @ActionInput(name = "url", label = "@text/actionLaunchBrowserInputUrlLabel", description = "@text/actionLaunchBrowserInputUrlDesc") String url) {
+ getConnectedSocket().ifPresent(control -> control.launchBrowser(url, createResponseListener()));
+ }
+
+ private List<AppInfo> getAppInfos() {
+ LGWebOSHandler lgWebOSHandler = getLGWebOSHandler();
+
+ if (!this.getConnectedSocket().isPresent()) {
+ return Collections.emptyList();
+ }
+
+ List<AppInfo> appInfos = lgWebOSHandler.getLauncherApplication()
+ .getAppInfos(lgWebOSHandler.getThing().getUID());
+ if (appInfos == null) {
+ logger.warn("No AppInfos found for device with ThingID {}.", lgWebOSHandler.getThing().getUID());
+ return Collections.emptyList();
+ }
+ return appInfos;
+ }
+
+ @RuleAction(label = "@text/actionLaunchApplicationLabel", description = "@text/actionLaunchApplicationDesc")
+ public void launchApplication(
+ @ActionInput(name = "appId", label = "@text/actionLaunchApplicationInputAppIDLabel", description = "@text/actionLaunchApplicationInputAppIDDesc") String appId) {
+ Optional<AppInfo> appInfo = getAppInfos().stream().filter(a -> a.getId().equals(appId)).findFirst();
+ if (appInfo.isPresent()) {
+ getConnectedSocket()
+ .ifPresent(control -> control.launchAppWithInfo(appInfo.get(), createResponseListener()));
+ } else {
+ logger.warn("Device with ThingID {} does not support any app with id: {}.",
+ getLGWebOSHandler().getThing().getUID(), appId);
+ }
+ }
+
+ @RuleAction(label = "@text/actionLaunchApplicationWithParamsLabel", description = "@text/actionLaunchApplicationWithParamsDesc")
+ public void launchApplication(
+ @ActionInput(name = "appId", label = "@text/actionLaunchApplicationInputAppIDLabel", description = "@text/actionLaunchApplicationInputAppIDDesc") String appId,
+ @ActionInput(name = "params", label = "@text/actionLaunchApplicationInputParamsLabel", description = "@text/actionLaunchApplicationInputParamsDesc") String params) {
+ try {
+ JsonParser parser = new JsonParser();
+ JsonObject payload = (JsonObject) parser.parse(params);
+
+ Optional<AppInfo> appInfo = getAppInfos().stream().filter(a -> a.getId().equals(appId)).findFirst();
+ if (appInfo.isPresent()) {
+ getConnectedSocket().ifPresent(
+ control -> control.launchAppWithInfo(appInfo.get(), payload, createResponseListener()));
+ } else {
+ logger.warn("Device with ThingID {} does not support any app with id: {}.",
+ getLGWebOSHandler().getThing().getUID(), appId);
+ }
+
+ } catch (JsonParseException ex) {
+ logger.warn("Parameters value ({}) is not in a valid JSON format. {}", params, ex.getMessage());
+ return;
+ }
+ }
+
+ @RuleAction(label = "@text/actionSendTextLabel", description = "@text/actionSendTextDesc")
+ public void sendText(
+ @ActionInput(name = "text", label = "@text/actionSendTextInputTextLabel", description = "@text/actionSendTextInputTextDesc") String text) {
+ getConnectedSocket().ifPresent(control -> {
+ ServiceSubscription<TextInputStatusInfo> subscription = control.subscribeTextInputStatus(textInputListener);
+ control.sendText(text);
+ control.unsubscribe(subscription);
+ });
+ }
+
+ @RuleAction(label = "@text/actionSendButtonLabel", description = "@text/actionSendButtonDesc")
+ public void sendButton(
+ @ActionInput(name = "text", label = "@text/actionSendButtonInputButtonLabel", description = "@text/actionSendButtonInputButtonDesc") String button) {
+ try {
+ switch (Button.valueOf(button)) {
+ case UP:
+ getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(ButtonType.UP)));
+ break;
+ case DOWN:
+ getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(ButtonType.DOWN)));
+ break;
+ case LEFT:
+ getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(ButtonType.LEFT)));
+ break;
+ case RIGHT:
+ getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(ButtonType.RIGHT)));
+ break;
+ case BACK:
+ getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(ButtonType.BACK)));
+ break;
+ case DELETE:
+ getConnectedSocket().ifPresent(control -> control.sendDelete());
+ break;
+ case ENTER:
+ getConnectedSocket().ifPresent(control -> control.sendEnter());
+ break;
+ case HOME:
+ getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button("HOME")));
+ break;
+ case OK:
+ getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.click()));
+ break;
+ }
+ } catch (IllegalArgumentException ex) {
+ logger.warn("{} is not a valid value for button - available are: {}", button,
+ Stream.of(Button.values()).map(b -> b.name()).collect(Collectors.joining(", ")));
+ }
+ }
+
+ @RuleAction(label = "@text/actionIncreaseChannelLabel", description = "@text/actionIncreaseChannelDesc")
+ public void increaseChannel() {
+ getConnectedSocket().ifPresent(control -> control.channelUp(createResponseListener()));
+ }
+
+ @RuleAction(label = "@text/actionDecreaseChannelLabel", description = "@text/actionDecreaseChannelDesc")
+ public void decreaseChannel() {
+ getConnectedSocket().ifPresent(control -> control.channelDown(createResponseListener()));
+ }
+
+ @RuleAction(label = "@text/actionSendRCButtonLabel", description = "@text/actionSendRCButtonDesc")
+ public void sendRCButton(
+ @ActionInput(name = "text", label = "@text/actionSendRCButtonInputTextLabel", description = "@text/actionSendRCButtonInputTextDesc") String rcButton) {
+ getConnectedSocket().ifPresent(control -> control.executeMouse(s -> s.button(rcButton)));
+ }
+
+ private Optional<LGWebOSTVSocket> getConnectedSocket() {
+ LGWebOSHandler lgWebOSHandler = getLGWebOSHandler();
+ final LGWebOSTVSocket socket = lgWebOSHandler.getSocket();
+
+ if (socket.getState() != State.REGISTERED) {
+ logger.warn("Device with ThingID {} is currently not connected.", lgWebOSHandler.getThing().getUID());
+ return Optional.empty();
+ }
+
+ return Optional.of(socket);
+ }
+
+ private ResponseListener<TextInputStatusInfo> createTextInputStatusListener() {
+ return new ResponseListener<TextInputStatusInfo>() {
+
+ @Override
+ public void onError(@Nullable String error) {
+ logger.warn("Response: {}", error);
+ }
+
+ @Override
+ public void onSuccess(@Nullable TextInputStatusInfo info) {
+ logger.debug("Response: {}", info == null ? "OK" : info.getRawData());
+ }
+ };
+ }
+
+ private <O> ResponseListener<O> createResponseListener() {
+ return new ResponseListener<O>() {
+
+ @Override
+ public void onError(@Nullable String error) {
+ logger.warn("Response: {}", error);
+ }
+
+ @Override
+ public void onSuccess(@Nullable O object) {
+ logger.debug("Response: {}", object == null ? "OK" : object.toString());
+ }
+ };
+ }
+
+ // delegation methods for "legacy" rule support
+
+ public static void showToast(@Nullable ThingActions actions, String text) throws IOException {
+ if (actions instanceof LGWebOSActions) {
+ ((LGWebOSActions) actions).showToast(text);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LGWebOSActions");
+ }
+ }
+
+ public static void showToast(@Nullable ThingActions actions, String icon, String text) throws IOException {
+ if (actions instanceof LGWebOSActions) {
+ ((LGWebOSActions) actions).showToast(icon, text);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LGWebOSActions");
+ }
+ }
+
+ public static void launchBrowser(@Nullable ThingActions actions, String url) {
+ if (actions instanceof LGWebOSActions) {
+ ((LGWebOSActions) actions).launchBrowser(url);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LGWebOSActions");
+ }
+ }
+
+ public static void launchApplication(@Nullable ThingActions actions, String appId) {
+ if (actions instanceof LGWebOSActions) {
+ ((LGWebOSActions) actions).launchApplication(appId);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LGWebOSActions");
+ }
+ }
+
+ public static void launchApplication(@Nullable ThingActions actions, String appId, String param) {
+ if (actions instanceof LGWebOSActions) {
+ ((LGWebOSActions) actions).launchApplication(appId, param);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LGWebOSActions");
+ }
+ }
+
+ public static void sendText(@Nullable ThingActions actions, String text) {
+ if (actions instanceof LGWebOSActions) {
+ ((LGWebOSActions) actions).sendText(text);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LGWebOSActions");
+ }
+ }
+
+ public static void sendButton(@Nullable ThingActions actions, String button) {
+ if (actions instanceof LGWebOSActions) {
+ ((LGWebOSActions) actions).sendButton(button);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LGWebOSActions");
+ }
+ }
+
+ public static void increaseChannel(@Nullable ThingActions actions) {
+ if (actions instanceof LGWebOSActions) {
+ ((LGWebOSActions) actions).increaseChannel();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LGWebOSActions");
+ }
+ }
+
+ public static void decreaseChannel(@Nullable ThingActions actions) {
+ if (actions instanceof LGWebOSActions) {
+ ((LGWebOSActions) actions).decreaseChannel();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LGWebOSActions");
+ }
+ }
+
+ public static void sendRCButton(@Nullable ThingActions actions, String rcButton) {
+ if (actions instanceof LGWebOSActions) {
+ ((LGWebOSActions) actions).sendRCButton(rcButton);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of LGWebOSActions");
+ }
+ }
+}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.websocket.client.WebSocketClient;
-import org.openhab.binding.lgwebos.action.LGWebOSActions;
import org.openhab.binding.lgwebos.internal.ChannelHandler;
import org.openhab.binding.lgwebos.internal.LGWebOSBindingConstants;
import org.openhab.binding.lgwebos.internal.LGWebOSStateDescriptionOptionProvider;
import org.openhab.binding.lgwebos.internal.VolumeControlMute;
import org.openhab.binding.lgwebos.internal.VolumeControlVolume;
import org.openhab.binding.lgwebos.internal.WakeOnLanUtility;
+import org.openhab.binding.lgwebos.internal.action.LGWebOSActions;
import org.openhab.binding.lgwebos.internal.handler.LGWebOSTVSocket.WebOSTVSocketListener;
import org.openhab.binding.lgwebos.internal.handler.core.AppInfo;
import org.openhab.binding.lgwebos.internal.handler.core.ResponseListener;
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.lutron.action;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.lutron.internal.handler.DimmerHandler;
-import org.openhab.binding.lutron.internal.protocol.LutronDuration;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link DimmerActions} defines thing actions for DimmerHandler.
- *
- * @author Bob Adair - Initial contribution
- */
-@ThingActionsScope(name = "lutron")
-@NonNullByDefault
-public class DimmerActions implements ThingActions, IDimmerActions {
- private final Logger logger = LoggerFactory.getLogger(DimmerActions.class);
-
- private @Nullable DimmerHandler handler;
-
- public DimmerActions() {
- logger.trace("Lutron Dimmer actions service created");
- }
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- if (handler instanceof DimmerHandler) {
- this.handler = (DimmerHandler) handler;
- }
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return handler;
- }
-
- /**
- * The setLevel dimmer thing action
- */
- @Override
- @RuleAction(label = "setLevel", description = "Send set level command with fade and delay times")
- public void setLevel(
- @ActionInput(name = "level", label = "Dimmer Level", description = "New dimmer level (0-100)") @Nullable Double level,
- @ActionInput(name = "fadeTime", label = "Fade Time", description = "Time to fade to new level (seconds)") @Nullable Double fadeTime,
- @ActionInput(name = "delayTime", label = "Delay Time", description = "Delay before starting fade (seconds)") @Nullable Double delayTime) {
- DimmerHandler dimmerHandler = handler;
- if (dimmerHandler == null) {
- logger.debug("Handler not set for Dimmer thing actions.");
- return;
- }
- if (level == null) {
- logger.debug("Ignoring setLevel command due to null level value.");
- return;
- }
- if (fadeTime == null) {
- logger.debug("Ignoring setLevel command due to null value for fadeTime.");
- return;
- }
- if (delayTime == null) {
- logger.debug("Ignoring setLevel command due to null value for delayTime.");
- return;
- }
-
- Double lightLevel = level;
- if (lightLevel > 100.0) {
- lightLevel = 100.0;
- } else if (lightLevel < 0.0) {
- lightLevel = 0.0;
- }
- try {
- dimmerHandler.setLightLevel(new BigDecimal(lightLevel).setScale(2, RoundingMode.HALF_UP),
- new LutronDuration(fadeTime), new LutronDuration(delayTime));
- } catch (IllegalArgumentException e) {
- logger.debug("Ignoring setLevel command due to illegal argument exception: {}", e.getMessage());
- }
- }
-
- /**
- * Static setLevel method for Rules DSL backward compatibility
- */
- public static void setLevel(@Nullable ThingActions actions, @Nullable Double level, @Nullable Double fadeTime,
- @Nullable Double delayTime) {
- invokeMethodOf(actions).setLevel(level, fadeTime, delayTime); // Replace when core issue #1536 is fixed
- }
-
- /**
- * This is only necessary to work around a bug in openhab-core (issue #1536). It should be removed once that is
- * resolved.
- */
- private static IDimmerActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(DimmerActions.class.getName())) {
- if (actions instanceof IDimmerActions) {
- return (IDimmerActions) actions;
- } else {
- return (IDimmerActions) Proxy.newProxyInstance(IDimmerActions.class.getClassLoader(),
- new Class[] { IDimmerActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of DimmerActions");
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.lutron.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link IDimmerActions} interface defines the interface for all thing actions supported by the dimmer thing.
- * This is only necessary to work around a bug in openhab-core (issue #1536). It should be removed once that is
- * resolved.
- *
- * @author Bob Adair - Initial contribution
- *
- */
-@NonNullByDefault
-public interface IDimmerActions {
-
- public void setLevel(@Nullable Double level, @Nullable Double fadeTime, @Nullable Double delayTime);
-}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.lutron.internal.action;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.lutron.internal.handler.DimmerHandler;
+import org.openhab.binding.lutron.internal.protocol.LutronDuration;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link DimmerActions} defines thing actions for DimmerHandler.
+ *
+ * @author Bob Adair - Initial contribution
+ */
+@ThingActionsScope(name = "lutron")
+@NonNullByDefault
+public class DimmerActions implements ThingActions {
+ private final Logger logger = LoggerFactory.getLogger(DimmerActions.class);
+
+ private @Nullable DimmerHandler handler;
+
+ public DimmerActions() {
+ logger.trace("Lutron Dimmer actions service created");
+ }
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ if (handler instanceof DimmerHandler) {
+ this.handler = (DimmerHandler) handler;
+ }
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+
+ /**
+ * The setLevel dimmer thing action
+ */
+ @RuleAction(label = "send a set level command", description = "Send set level command with fade and delay times.")
+ public void setLevel(
+ @ActionInput(name = "level", label = "Dimmer Level", description = "New dimmer level (0-100)") @Nullable Double level,
+ @ActionInput(name = "fadeTime", label = "Fade Time", description = "Time to fade to new level (seconds)") @Nullable Double fadeTime,
+ @ActionInput(name = "delayTime", label = "Delay Time", description = "Delay before starting fade (seconds)") @Nullable Double delayTime) {
+ DimmerHandler dimmerHandler = handler;
+ if (dimmerHandler == null) {
+ logger.debug("Handler not set for Dimmer thing actions.");
+ return;
+ }
+ if (level == null) {
+ logger.debug("Ignoring setLevel command due to null level value.");
+ return;
+ }
+ if (fadeTime == null) {
+ logger.debug("Ignoring setLevel command due to null value for fadeTime.");
+ return;
+ }
+ if (delayTime == null) {
+ logger.debug("Ignoring setLevel command due to null value for delayTime.");
+ return;
+ }
+
+ Double lightLevel = level;
+ if (lightLevel > 100.0) {
+ lightLevel = 100.0;
+ } else if (lightLevel < 0.0) {
+ lightLevel = 0.0;
+ }
+ try {
+ dimmerHandler.setLightLevel(new BigDecimal(lightLevel).setScale(2, RoundingMode.HALF_UP),
+ new LutronDuration(fadeTime), new LutronDuration(delayTime));
+ } catch (IllegalArgumentException e) {
+ logger.debug("Ignoring setLevel command due to illegal argument exception: {}", e.getMessage());
+ }
+ }
+
+ /**
+ * Static setLevel method for Rules DSL backward compatibility
+ */
+ public static void setLevel(@Nullable ThingActions actions, @Nullable Double level, @Nullable Double fadeTime,
+ @Nullable Double delayTime) {
+ if (actions instanceof DimmerActions) {
+ ((DimmerActions) actions).setLevel(level, fadeTime, delayTime);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of DimmerActions");
+ }
+ }
+}
import java.util.Collections;
import java.util.concurrent.atomic.AtomicReference;
-import org.openhab.binding.lutron.action.DimmerActions;
+import org.openhab.binding.lutron.internal.action.DimmerActions;
import org.openhab.binding.lutron.internal.config.DimmerConfig;
import org.openhab.binding.lutron.internal.protocol.LutronCommandType;
import org.openhab.binding.lutron.internal.protocol.LutronDuration;
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.mail.action;
-
-import java.util.List;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link ISendMailActions} interface defines rule actions for sending mail
- *
- * @author Jan N. Klug - Initial contribution
- */
-@NonNullByDefault
-public interface ISendMailActions {
- Boolean sendMail(@Nullable String recipient, @Nullable String subject, @Nullable String text,
- @Nullable List<String> urlStringList);
-
- Boolean sendHtmlMail(@Nullable String recipient, @Nullable String subject, @Nullable String html,
- @Nullable List<String> urlStringList);
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.mail.action;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.net.MalformedURLException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.mail.internet.AddressException;
-
-import org.apache.commons.mail.EmailException;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.mail.internal.MailBuilder;
-import org.openhab.binding.mail.internal.SMTPHandler;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.ActionOutput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link SendMailActions} class defines rule actions for sending mail
- *
- * @author Jan N. Klug - Initial contribution
- */
-@ThingActionsScope(name = "mail")
-@NonNullByDefault
-public class SendMailActions implements ThingActions, ISendMailActions {
-
- private final Logger logger = LoggerFactory.getLogger(SendMailActions.class);
-
- private @Nullable SMTPHandler handler;
-
- @RuleAction(label = "Send Text Mail", description = "sends a text mail")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMail(
- @ActionInput(name = "recipient") @Nullable String recipient,
- @ActionInput(name = "subject") @Nullable String subject,
- @ActionInput(name = "text") @Nullable String text) {
- return sendMail(recipient, subject, text, new ArrayList<>());
- }
-
- @RuleAction(label = "Send Text Mail", description = "sends a text mail with URL attachment")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMail(
- @ActionInput(name = "recipient") @Nullable String recipient,
- @ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "text") @Nullable String text,
- @ActionInput(name = "url") @Nullable String urlString) {
- List<String> urlList = new ArrayList<>();
- if (urlString != null) {
- urlList.add(urlString);
- }
- return sendMail(recipient, subject, text, urlList);
- }
-
- @Override
- @RuleAction(label = "Send Text Mail", description = "sends a text mail with several URL attachments")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMail(
- @ActionInput(name = "recipient") @Nullable String recipient,
- @ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "text") @Nullable String text,
- @ActionInput(name = "urlList") @Nullable List<String> urlStringList) {
- if (recipient == null) {
- logger.warn("Cannot send mail as recipient is missing.");
- return false;
- }
-
- try {
- MailBuilder builder = new MailBuilder(recipient);
-
- if (subject != null && !subject.isEmpty()) {
- builder.withSubject(subject);
- }
- if (text != null && !text.isEmpty()) {
- builder.withText(text);
- }
- if (urlStringList != null) {
- for (String urlString : urlStringList) {
- builder.withURLAttachment(urlString);
- }
- }
-
- final SMTPHandler handler = this.handler;
- if (handler == null) {
- logger.info("Handler is null, cannot send mail.");
- return false;
- } else {
- return handler.sendMail(builder.build());
- }
- } catch (AddressException | MalformedURLException | EmailException e) {
- logger.warn("Could not send mail: {}", e.getMessage());
- return false;
- }
- }
-
- public static boolean sendMail(@Nullable ThingActions actions, @Nullable String recipient, @Nullable String subject,
- @Nullable String text) {
- return SendMailActions.sendMail(actions, recipient, subject, text, new ArrayList<>());
- }
-
- public static boolean sendMail(@Nullable ThingActions actions, @Nullable String recipient, @Nullable String subject,
- @Nullable String text, @Nullable String urlString) {
- List<String> urlList = new ArrayList<>();
- if (urlString != null) {
- urlList.add(urlString);
- }
- return SendMailActions.sendMail(actions, recipient, subject, text, urlList);
- }
-
- public static boolean sendMail(@Nullable ThingActions actions, @Nullable String recipient, @Nullable String subject,
- @Nullable String text, @Nullable List<String> urlStringList) {
- return invokeMethodOf(actions).sendMail(recipient, subject, text, urlStringList);
- }
-
- @RuleAction(label = "Send HTML Mail", description = "sends a HTML mail")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendHtmlMail(
- @ActionInput(name = "recipient") @Nullable String recipient,
- @ActionInput(name = "subject") @Nullable String subject,
- @ActionInput(name = "html") @Nullable String html) {
- return sendHtmlMail(recipient, subject, html, new ArrayList<>());
- }
-
- @RuleAction(label = "Send HTML Mail", description = "sends a HTML mail with URL attachment")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendHtmlMail(
- @ActionInput(name = "recipient") @Nullable String recipient,
- @ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "html") @Nullable String html,
- @ActionInput(name = "url") @Nullable String urlString) {
- List<String> urlList = new ArrayList<>();
- if (urlString != null) {
- urlList.add(urlString);
- }
- return sendHtmlMail(recipient, subject, html, urlList);
- }
-
- @Override
- @RuleAction(label = "Send HTML Mail", description = "sends a HTML mail with several URL attachments")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendHtmlMail(
- @ActionInput(name = "recipient") @Nullable String recipient,
- @ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "html") @Nullable String html,
- @ActionInput(name = "urlList") @Nullable List<String> urlStringList) {
- if (recipient == null) {
- logger.warn("Cannot send mail as recipient is missing.");
- return false;
- }
-
- try {
- MailBuilder builder = new MailBuilder(recipient);
-
- if (subject != null && !subject.isEmpty()) {
- builder.withSubject(subject);
- }
- if (html != null && !html.isEmpty()) {
- builder.withHtml(html);
- }
- if (urlStringList != null) {
- for (String urlString : urlStringList) {
- builder.withURLAttachment(urlString);
- }
- }
-
- final SMTPHandler handler = this.handler;
- if (handler == null) {
- logger.warn("Handler is null, cannot send mail.");
- return false;
- } else {
- return handler.sendMail(builder.build());
- }
- } catch (AddressException | MalformedURLException | EmailException e) {
- logger.warn("Could not send mail: {}", e.getMessage());
- return false;
- }
- }
-
- public static boolean sendHtmlMail(@Nullable ThingActions actions, @Nullable String recipient,
- @Nullable String subject, @Nullable String html) {
- return SendMailActions.sendHtmlMail(actions, recipient, subject, html, new ArrayList<>());
- }
-
- public static boolean sendHtmlMail(@Nullable ThingActions actions, @Nullable String recipient,
- @Nullable String subject, @Nullable String html, @Nullable String urlString) {
- List<String> urlList = new ArrayList<>();
- if (urlString != null) {
- urlList.add(urlString);
- }
- return SendMailActions.sendHtmlMail(actions, recipient, subject, html, urlList);
- }
-
- public static boolean sendHtmlMail(@Nullable ThingActions actions, @Nullable String recipient,
- @Nullable String subject, @Nullable String html, @Nullable List<String> urlStringList) {
- return invokeMethodOf(actions).sendHtmlMail(recipient, subject, html, urlStringList);
- }
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- if (handler instanceof SMTPHandler) {
- this.handler = (SMTPHandler) handler;
- }
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- private static ISendMailActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(SendMailActions.class.getName())) {
- if (actions instanceof ISendMailActions) {
- return (ISendMailActions) actions;
- } else {
- return (ISendMailActions) Proxy.newProxyInstance(ISendMailActions.class.getClassLoader(),
- new Class[] { ISendMailActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of SendMailActions");
- }
-}
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.mail.action.SendMailActions;
+import org.openhab.binding.mail.internal.action.SendMailActions;
import org.openhab.binding.mail.internal.config.SMTPConfig;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.mail.internal.action;
+
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.internet.AddressException;
+
+import org.apache.commons.mail.EmailException;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.mail.internal.MailBuilder;
+import org.openhab.binding.mail.internal.SMTPHandler;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.ActionOutput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link SendMailActions} class defines rule actions for sending mail
+ *
+ * @author Jan N. Klug - Initial contribution
+ */
+@ThingActionsScope(name = "mail")
+@NonNullByDefault
+public class SendMailActions implements ThingActions {
+
+ private final Logger logger = LoggerFactory.getLogger(SendMailActions.class);
+
+ private @Nullable SMTPHandler handler;
+
+ @RuleAction(label = "send a text mail", description = "Sends a text mail.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMail(
+ @ActionInput(name = "recipient") @Nullable String recipient,
+ @ActionInput(name = "subject") @Nullable String subject,
+ @ActionInput(name = "text") @Nullable String text) {
+ return sendMail(recipient, subject, text, new ArrayList<>());
+ }
+
+ @RuleAction(label = "send a text mail", description = "Sends a text mail with URL attachment.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMail(
+ @ActionInput(name = "recipient") @Nullable String recipient,
+ @ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "text") @Nullable String text,
+ @ActionInput(name = "url") @Nullable String urlString) {
+ List<String> urlList = new ArrayList<>();
+ if (urlString != null) {
+ urlList.add(urlString);
+ }
+ return sendMail(recipient, subject, text, urlList);
+ }
+
+ @RuleAction(label = "send a text mail", description = "Sends a text mail with several URL attachments.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMail(
+ @ActionInput(name = "recipient") @Nullable String recipient,
+ @ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "text") @Nullable String text,
+ @ActionInput(name = "urlList") @Nullable List<String> urlStringList) {
+ if (recipient == null) {
+ logger.warn("Cannot send mail as recipient is missing.");
+ return false;
+ }
+
+ try {
+ MailBuilder builder = new MailBuilder(recipient);
+
+ if (subject != null && !subject.isEmpty()) {
+ builder.withSubject(subject);
+ }
+ if (text != null && !text.isEmpty()) {
+ builder.withText(text);
+ }
+ if (urlStringList != null) {
+ for (String urlString : urlStringList) {
+ builder.withURLAttachment(urlString);
+ }
+ }
+
+ final SMTPHandler handler = this.handler;
+ if (handler == null) {
+ logger.info("Handler is null, cannot send mail.");
+ return false;
+ } else {
+ return handler.sendMail(builder.build());
+ }
+ } catch (AddressException | MalformedURLException | EmailException e) {
+ logger.warn("Could not send mail: {}", e.getMessage());
+ return false;
+ }
+ }
+
+ public static boolean sendMail(@Nullable ThingActions actions, @Nullable String recipient, @Nullable String subject,
+ @Nullable String text) {
+ return SendMailActions.sendMail(actions, recipient, subject, text, new ArrayList<>());
+ }
+
+ public static boolean sendMail(@Nullable ThingActions actions, @Nullable String recipient, @Nullable String subject,
+ @Nullable String text, @Nullable String urlString) {
+ List<String> urlList = new ArrayList<>();
+ if (urlString != null) {
+ urlList.add(urlString);
+ }
+ return SendMailActions.sendMail(actions, recipient, subject, text, urlList);
+ }
+
+ public static boolean sendMail(@Nullable ThingActions actions, @Nullable String recipient, @Nullable String subject,
+ @Nullable String text, @Nullable List<String> urlStringList) {
+ if (actions instanceof SendMailActions) {
+ return ((SendMailActions) actions).sendMail(recipient, subject, text, urlStringList);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of SendMailActions");
+ }
+ }
+
+ @RuleAction(label = "send a HTML mail", description = "Sends a HTML mail.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendHtmlMail(
+ @ActionInput(name = "recipient") @Nullable String recipient,
+ @ActionInput(name = "subject") @Nullable String subject,
+ @ActionInput(name = "html") @Nullable String html) {
+ return sendHtmlMail(recipient, subject, html, new ArrayList<>());
+ }
+
+ @RuleAction(label = "send a HTML mail", description = "Sends a HTML mail with URL attachment.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendHtmlMail(
+ @ActionInput(name = "recipient") @Nullable String recipient,
+ @ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "html") @Nullable String html,
+ @ActionInput(name = "url") @Nullable String urlString) {
+ List<String> urlList = new ArrayList<>();
+ if (urlString != null) {
+ urlList.add(urlString);
+ }
+ return sendHtmlMail(recipient, subject, html, urlList);
+ }
+
+ @RuleAction(label = "send a HTML mail", description = "Sends a HTML mail with several URL attachments.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendHtmlMail(
+ @ActionInput(name = "recipient") @Nullable String recipient,
+ @ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "html") @Nullable String html,
+ @ActionInput(name = "urlList") @Nullable List<String> urlStringList) {
+ if (recipient == null) {
+ logger.warn("Cannot send mail as recipient is missing.");
+ return false;
+ }
+
+ try {
+ MailBuilder builder = new MailBuilder(recipient);
+
+ if (subject != null && !subject.isEmpty()) {
+ builder.withSubject(subject);
+ }
+ if (html != null && !html.isEmpty()) {
+ builder.withHtml(html);
+ }
+ if (urlStringList != null) {
+ for (String urlString : urlStringList) {
+ builder.withURLAttachment(urlString);
+ }
+ }
+
+ final SMTPHandler handler = this.handler;
+ if (handler == null) {
+ logger.warn("Handler is null, cannot send mail.");
+ return false;
+ } else {
+ return handler.sendMail(builder.build());
+ }
+ } catch (AddressException | MalformedURLException | EmailException e) {
+ logger.warn("Could not send mail: {}", e.getMessage());
+ return false;
+ }
+ }
+
+ public static boolean sendHtmlMail(@Nullable ThingActions actions, @Nullable String recipient,
+ @Nullable String subject, @Nullable String html) {
+ return SendMailActions.sendHtmlMail(actions, recipient, subject, html, new ArrayList<>());
+ }
+
+ public static boolean sendHtmlMail(@Nullable ThingActions actions, @Nullable String recipient,
+ @Nullable String subject, @Nullable String html, @Nullable String urlString) {
+ List<String> urlList = new ArrayList<>();
+ if (urlString != null) {
+ urlList.add(urlString);
+ }
+ return SendMailActions.sendHtmlMail(actions, recipient, subject, html, urlList);
+ }
+
+ public static boolean sendHtmlMail(@Nullable ThingActions actions, @Nullable String recipient,
+ @Nullable String subject, @Nullable String html, @Nullable List<String> urlStringList) {
+ if (actions instanceof SendMailActions) {
+ return ((SendMailActions) actions).sendHtmlMail(recipient, subject, html, urlStringList);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of SendMailActions");
+ }
+ }
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ if (handler instanceof SMTPHandler) {
+ this.handler = (SMTPHandler) handler;
+ }
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.max.actions;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.max.internal.actions.IMaxCubeActions;
-import org.openhab.binding.max.internal.handler.MaxCubeBridgeHandler;
-import org.openhab.core.automation.annotation.ActionOutput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link MaxCubeActions} class defines rule actions for MAX! Cube
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-@ThingActionsScope(name = "max-cube")
-@NonNullByDefault
-public class MaxCubeActions implements ThingActions, IMaxCubeActions {
-
- private final Logger logger = LoggerFactory.getLogger(MaxCubeActions.class);
-
- private @Nullable MaxCubeBridgeHandler handler;
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- if (handler instanceof MaxCubeBridgeHandler) {
- this.handler = (MaxCubeBridgeHandler) handler;
- }
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- @Override
- @RuleAction(label = "Backup Cube Data", description = "Creates a backup of the MAX! Cube data.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean backup() {
- MaxCubeBridgeHandler actionsHandler = handler;
- if (actionsHandler == null) {
- logger.info("MaxCubeActions: Action service ThingHandler is null!");
- return false;
- }
- actionsHandler.backup();
- return true;
- }
-
- public static boolean backup(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).backup();
- }
-
- @Override
- @RuleAction(label = "Reset Cube Configuration", description = "Resets the MAX! Cube room and device information. Devices will need to be included again!")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean resetConfig() {
- MaxCubeBridgeHandler actionsHandler = handler;
- if (actionsHandler == null) {
- logger.info("MaxCubeActions: Action service ThingHandler is null!");
- return false;
- }
- actionsHandler.cubeConfigReset();
- return true;
- }
-
- public static boolean reset(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).resetConfig();
- }
-
- @Override
- @RuleAction(label = "Restart Cube", description = "Restarts the MAX! Cube.")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean reboot() {
- MaxCubeBridgeHandler actionsHandler = handler;
- if (actionsHandler == null) {
- logger.info("MaxCubeActions: Action service ThingHandler is null!");
- return false;
- }
- actionsHandler.cubeReboot();
- return true;
- }
-
- public static boolean reboot(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).reboot();
- }
-
- private static IMaxCubeActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(MaxCubeActions.class.getName())) {
- if (actions instanceof IMaxCubeActions) {
- return (IMaxCubeActions) actions;
- } else {
- return (IMaxCubeActions) Proxy.newProxyInstance(IMaxCubeActions.class.getClassLoader(),
- new Class[] { IMaxCubeActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of MaxCubeActions");
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.max.actions;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.max.internal.actions.IMaxDevicesActions;
-import org.openhab.binding.max.internal.handler.MaxDevicesHandler;
-import org.openhab.core.automation.annotation.ActionOutput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link MaxDevicesActions} class defines rule actions for MAX! devices
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-@ThingActionsScope(name = "max-devices")
-@NonNullByDefault
-public class MaxDevicesActions implements ThingActions, IMaxDevicesActions {
-
- private final Logger logger = LoggerFactory.getLogger(MaxDevicesActions.class);
-
- private @Nullable MaxDevicesHandler handler;
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- if (handler instanceof MaxDevicesHandler) {
- this.handler = (MaxDevicesHandler) handler;
- }
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- @Override
- @RuleAction(label = "Delete Device from Cube", description = "Deletes the device from the MAX! Cube. Device will need to be included again!")
- public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean deleteFromCube() {
- MaxDevicesHandler actionsHandler = handler;
- if (actionsHandler == null) {
- logger.info("MaxDevicesActions: Action service ThingHandler is null!");
- return false;
- }
- actionsHandler.deviceDelete();
- return true;
- }
-
- public static boolean deleteFromCube(@Nullable ThingActions actions) {
- return invokeMethodOf(actions).deleteFromCube();
- }
-
- private static IMaxDevicesActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(MaxDevicesActions.class.getName())) {
- if (actions instanceof IMaxDevicesActions) {
- return (IMaxDevicesActions) actions;
- } else {
- return (IMaxDevicesActions) Proxy.newProxyInstance(IMaxDevicesActions.class.getClassLoader(),
- new Class[] { IMaxDevicesActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of MaxDevicesActions");
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.max.internal.actions;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.max.actions.MaxCubeActions;
-
-/**
- * The {@link IMaxCubeActions} defines the interface for all thing actions supported by the binding.
- * These methods, parameters, and return types are explained in {@link MaxCubeActions}.
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-@NonNullByDefault
-public interface IMaxCubeActions {
-
- Boolean backup();
-
- Boolean resetConfig();
-
- Boolean reboot();
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.max.internal.actions;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.max.actions.MaxDevicesActions;
-
-/**
- * The {@link IMaxDevicesActions} defines the interface for all thing actions supported by the binding.
- * These methods, parameters, and return types are explained in {@link MaxDevicesActions}.
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-@NonNullByDefault
-public interface IMaxDevicesActions {
-
- Boolean deleteFromCube();
-}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.max.internal.actions;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.max.internal.handler.MaxCubeBridgeHandler;
+import org.openhab.core.automation.annotation.ActionOutput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link MaxCubeActions} class defines rule actions for MAX! Cube
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+@ThingActionsScope(name = "max-cube")
+@NonNullByDefault
+public class MaxCubeActions implements ThingActions {
+
+ private final Logger logger = LoggerFactory.getLogger(MaxCubeActions.class);
+
+ private @Nullable MaxCubeBridgeHandler handler;
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ if (handler instanceof MaxCubeBridgeHandler) {
+ this.handler = (MaxCubeBridgeHandler) handler;
+ }
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+
+ @RuleAction(label = "backup the Cube data", description = "Creates a backup of the MAX! Cube data.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean backup() {
+ MaxCubeBridgeHandler actionsHandler = handler;
+ if (actionsHandler == null) {
+ logger.info("MaxCubeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ actionsHandler.backup();
+ return true;
+ }
+
+ public static boolean backup(@Nullable ThingActions actions) {
+ if (actions instanceof MaxCubeActions) {
+ return ((MaxCubeActions) actions).backup();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of MaxCubeActions");
+ }
+ }
+
+ @RuleAction(label = "reset the Cube configuration", description = "Resets the MAX! Cube room and device information. Devices will need to be included again!")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean resetConfig() {
+ MaxCubeBridgeHandler actionsHandler = handler;
+ if (actionsHandler == null) {
+ logger.info("MaxCubeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ actionsHandler.cubeConfigReset();
+ return true;
+ }
+
+ public static boolean reset(@Nullable ThingActions actions) {
+ if (actions instanceof MaxCubeActions) {
+ return ((MaxCubeActions) actions).resetConfig();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of MaxCubeActions");
+ }
+ }
+
+ @RuleAction(label = "restart the Cube", description = "Restarts the MAX! Cube.")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean reboot() {
+ MaxCubeBridgeHandler actionsHandler = handler;
+ if (actionsHandler == null) {
+ logger.info("MaxCubeActions: Action service ThingHandler is null!");
+ return false;
+ }
+ actionsHandler.cubeReboot();
+ return true;
+ }
+
+ public static boolean reboot(@Nullable ThingActions actions) {
+ if (actions instanceof MaxCubeActions) {
+ return ((MaxCubeActions) actions).reboot();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of MaxCubeActions");
+ }
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.max.internal.actions;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.max.internal.handler.MaxDevicesHandler;
+import org.openhab.core.automation.annotation.ActionOutput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link MaxDevicesActions} class defines rule actions for MAX! devices
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+@ThingActionsScope(name = "max-devices")
+@NonNullByDefault
+public class MaxDevicesActions implements ThingActions {
+
+ private final Logger logger = LoggerFactory.getLogger(MaxDevicesActions.class);
+
+ private @Nullable MaxDevicesHandler handler;
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ if (handler instanceof MaxDevicesHandler) {
+ this.handler = (MaxDevicesHandler) handler;
+ }
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+
+ @RuleAction(label = "delete the device from the Cube", description = "Deletes the device from the MAX! Cube. Device will need to be included again!")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean deleteFromCube() {
+ MaxDevicesHandler actionsHandler = handler;
+ if (actionsHandler == null) {
+ logger.info("MaxDevicesActions: Action service ThingHandler is null!");
+ return false;
+ }
+ actionsHandler.deviceDelete();
+ return true;
+ }
+
+ public static boolean deleteFromCube(@Nullable ThingActions actions) {
+ if (actions instanceof MaxDevicesActions) {
+ return ((MaxDevicesActions) actions).deleteFromCube();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of MaxDevicesActions");
+ }
+ }
+}
import javax.measure.quantity.Temperature;
-import org.openhab.binding.max.actions.MaxCubeActions;
import org.openhab.binding.max.internal.MaxBackupUtils;
import org.openhab.binding.max.internal.MaxBindingConstants;
+import org.openhab.binding.max.internal.actions.MaxCubeActions;
import org.openhab.binding.max.internal.command.ACommand;
import org.openhab.binding.max.internal.command.CCommand;
import org.openhab.binding.max.internal.command.CubeCommand;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-import org.openhab.binding.max.actions.MaxDevicesActions;
+import org.openhab.binding.max.internal.actions.MaxDevicesActions;
import org.openhab.binding.max.internal.command.CCommand;
import org.openhab.binding.max.internal.command.QCommand;
import org.openhab.binding.max.internal.command.SConfigCommand;
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.mpd.internal.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link IMPDActions} interface defines rule actions for sending commands to a Music Player Daemon
- *
- * @author Stefan Röllin - Initial contribution
- */
-@NonNullByDefault
-public interface IMPDActions {
-
- public void sendCommand(@Nullable String command, @Nullable String parameter);
-
- public void sendCommand(@Nullable String command);
-}
*/
package org.openhab.binding.mpd.internal.action;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.mpd.internal.handler.MPDHandler;
*/
@ThingActionsScope(name = "mpd")
@NonNullByDefault
-public class MPDActions implements ThingActions, IMPDActions {
+public class MPDActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(MPDActions.class);
return handler;
}
- @Override
- @RuleAction(label = "MPD : Send command", description = "Send a command to the Music Player Daemon.")
+ @RuleAction(label = "send a command with a parameter", description = "Send a command to the Music Player Daemon.")
public void sendCommand(@ActionInput(name = "command") @Nullable String command,
@ActionInput(name = "parameter") @Nullable String parameter) {
logger.debug("sendCommand called with {}", command);
}
}
- @Override
- @RuleAction(label = "MPD : Send command", description = "Send a command to the Music Player Daemon.")
+ @RuleAction(label = "send a command", description = "Send a command to the Music Player Daemon.")
public void sendCommand(@ActionInput(name = "command") @Nullable String command) {
logger.debug("sendCommand called with {}", command);
}
}
- private static IMPDActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(MPDActions.class.getName())) {
- if (actions instanceof IMPDActions) {
- return (IMPDActions) actions;
- } else {
- return (IMPDActions) Proxy.newProxyInstance(IMPDActions.class.getClassLoader(),
- new Class[] { IMPDActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of MPDActions");
- }
-
public static void sendCommand(@Nullable ThingActions actions, @Nullable String command,
@Nullable String parameter) {
- invokeMethodOf(actions).sendCommand(command, parameter);
+ if (actions instanceof MPDActions) {
+ ((MPDActions) actions).sendCommand(command, parameter);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of MPDActions");
+ }
}
public static void sendCommand(@Nullable ThingActions actions, @Nullable String command) {
- invokeMethodOf(actions).sendCommand(command);
+ if (actions instanceof MPDActions) {
+ ((MPDActions) actions).sendCommand(command);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of MPDActions");
+ }
}
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.mqtt.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link IMQTTActions} defines the interface for all thing actions supported by the binding.
- *
- * @author Laurent Garnier - Initial contribution
- */
-@NonNullByDefault
-public interface IMQTTActions {
-
- public void publishMQTT(@Nullable String topic, @Nullable String value, @Nullable Boolean retain);
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.mqtt.action;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.mqtt.handler.AbstractBrokerHandler;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This is the automation engine action handler service for the publishMQTT action.
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof MQTTActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link MQTTActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
- *
- * @author David Graeff - Initial contribution
- */
-@ThingActionsScope(name = "mqtt")
-@NonNullByDefault
-public class MQTTActions implements ThingActions, IMQTTActions {
- private final Logger logger = LoggerFactory.getLogger(MQTTActions.class);
- private @Nullable AbstractBrokerHandler handler;
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- this.handler = (AbstractBrokerHandler) handler;
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- @RuleAction(label = "@text/actionLabel", description = "@text/actionDesc")
- public void publishMQTT(
- @ActionInput(name = "topic", label = "@text/actionInputTopicLabel", description = "@text/actionInputTopicDesc") @Nullable String topic,
- @ActionInput(name = "value", label = "@text/actionInputValueLabel", description = "@text/actionInputValueDesc") @Nullable String value) {
- publishMQTT(topic, value, null);
- }
-
- @Override
- @RuleAction(label = "@text/actionLabel", description = "@text/actionDesc")
- public void publishMQTT(
- @ActionInput(name = "topic", label = "@text/actionInputTopicLabel", description = "@text/actionInputTopicDesc") @Nullable final String topic,
- @ActionInput(name = "value", label = "@text/actionInputValueLabel", description = "@text/actionInputValueDesc") @Nullable final String value,
- @ActionInput(name = "retain", label = "@text/actionInputRetainlabel", description = "@text/actionInputRetainDesc") @Nullable final Boolean retain) {
- AbstractBrokerHandler brokerHandler = handler;
- if (brokerHandler == null) {
- logger.warn("MQTT Action service ThingHandler is null!");
- return;
- }
- MqttBrokerConnection connection = brokerHandler.getConnection();
- if (connection == null) {
- logger.warn("MQTT Action service ThingHandler connection is null!");
- return;
- }
- if (value == null) {
- logger.debug("skipping MQTT publishing to topic '{}' due to null value.", topic);
- return;
- }
- if (topic == null) {
- logger.debug("skipping MQTT publishing of value '{}' as topic is null.", value);
- return;
- }
-
- connection.publish(topic, value.getBytes(), connection.getQos(), retain != null && retain.booleanValue())
- .thenRun(() -> {
- logger.debug("MQTT publish to {} performed", topic);
- }).exceptionally(e -> {
- logger.warn("MQTT publish to {} failed!", topic);
- return null;
- });
- }
-
- public static void publishMQTT(@Nullable ThingActions actions, @Nullable String topic, @Nullable String value) {
- publishMQTT(actions, topic, value, null);
- }
-
- public static void publishMQTT(@Nullable ThingActions actions, @Nullable String topic, @Nullable String value,
- @Nullable Boolean retain) {
- invokeMethodOf(actions).publishMQTT(topic, value, retain);
- }
-
- private static IMQTTActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(MQTTActions.class.getName())) {
- if (actions instanceof IMQTTActions) {
- return (IMQTTActions) actions;
- } else {
- return (IMQTTActions) Proxy.newProxyInstance(IMQTTActions.class.getClassLoader(),
- new Class[] { IMQTTActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of MQTTActions");
- }
-}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.mqtt.action.MQTTActions;
import org.openhab.binding.mqtt.discovery.MQTTTopicDiscoveryParticipant;
import org.openhab.binding.mqtt.discovery.TopicSubscribe;
+import org.openhab.binding.mqtt.internal.action.MQTTActions;
import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
import org.openhab.core.io.transport.mqtt.MqttConnectionObserver;
import org.openhab.core.io.transport.mqtt.MqttConnectionState;
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.mqtt.internal.action;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.mqtt.handler.AbstractBrokerHandler;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the automation engine action handler service for the publishMQTT action.
+ *
+ * @author David Graeff - Initial contribution
+ */
+@ThingActionsScope(name = "mqtt")
+@NonNullByDefault
+public class MQTTActions implements ThingActions {
+ private final Logger logger = LoggerFactory.getLogger(MQTTActions.class);
+ private @Nullable AbstractBrokerHandler handler;
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ this.handler = (AbstractBrokerHandler) handler;
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+
+ @RuleAction(label = "@text/actionLabel", description = "@text/actionDesc")
+ public void publishMQTT(
+ @ActionInput(name = "topic", label = "@text/actionInputTopicLabel", description = "@text/actionInputTopicDesc") @Nullable String topic,
+ @ActionInput(name = "value", label = "@text/actionInputValueLabel", description = "@text/actionInputValueDesc") @Nullable String value) {
+ publishMQTT(topic, value, null);
+ }
+
+ @RuleAction(label = "@text/actionLabel", description = "@text/actionDesc")
+ public void publishMQTT(
+ @ActionInput(name = "topic", label = "@text/actionInputTopicLabel", description = "@text/actionInputTopicDesc") @Nullable final String topic,
+ @ActionInput(name = "value", label = "@text/actionInputValueLabel", description = "@text/actionInputValueDesc") @Nullable final String value,
+ @ActionInput(name = "retain", label = "@text/actionInputRetainlabel", description = "@text/actionInputRetainDesc") @Nullable final Boolean retain) {
+ AbstractBrokerHandler brokerHandler = handler;
+ if (brokerHandler == null) {
+ logger.warn("MQTT Action service ThingHandler is null!");
+ return;
+ }
+ MqttBrokerConnection connection = brokerHandler.getConnection();
+ if (connection == null) {
+ logger.warn("MQTT Action service ThingHandler connection is null!");
+ return;
+ }
+ if (value == null) {
+ logger.debug("skipping MQTT publishing to topic '{}' due to null value.", topic);
+ return;
+ }
+ if (topic == null) {
+ logger.debug("skipping MQTT publishing of value '{}' as topic is null.", value);
+ return;
+ }
+
+ connection.publish(topic, value.getBytes(), connection.getQos(), retain != null && retain.booleanValue())
+ .thenRun(() -> {
+ logger.debug("MQTT publish to {} performed", topic);
+ }).exceptionally(e -> {
+ logger.warn("MQTT publish to {} failed!", topic);
+ return null;
+ });
+ }
+
+ public static void publishMQTT(@Nullable ThingActions actions, @Nullable String topic, @Nullable String value) {
+ publishMQTT(actions, topic, value, null);
+ }
+
+ public static void publishMQTT(@Nullable ThingActions actions, @Nullable String topic, @Nullable String value,
+ @Nullable Boolean retain) {
+ if (actions instanceof MQTTActions) {
+ ((MQTTActions) actions).publishMQTT(topic, value, retain);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of MQTTActions");
+ }
+ }
+}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.network.internal.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * The {@link INetworkActions} defines the interface for all thing actions supported by the binding.
- *
- * @author Wouter Born - Initial contribution
- */
-@NonNullByDefault
-public interface INetworkActions {
-
- void sendWakeOnLanPacket();
-}
*/
package org.openhab.binding.network.internal.action;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.network.internal.handler.NetworkHandler;
/**
* The class is responsible to call corresponding actions on {@link NetworkHandler}.
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof NetworkActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link NetworkActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
*
* @author Wouter Born - Initial contribution
*/
@ThingActionsScope(name = "network")
@NonNullByDefault
-public class NetworkActions implements ThingActions, INetworkActions {
+public class NetworkActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(NetworkActions.class);
return handler;
}
- @Override
- @RuleAction(label = "Send WoL Packet", description = "Send a Wake-on-LAN packet to wake the device")
+ @RuleAction(label = "send a WoL packet", description = "Send a Wake-on-LAN packet to wake the device.")
public void sendWakeOnLanPacket() {
NetworkHandler localHandler = handler;
if (localHandler != null) {
}
public static void sendWakeOnLanPacket(@Nullable ThingActions actions) {
- invokeMethodOf(actions).sendWakeOnLanPacket();
- }
-
- private static INetworkActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(NetworkActions.class.getName())) {
- if (actions instanceof INetworkActions) {
- return (INetworkActions) actions;
- } else {
- return (INetworkActions) Proxy.newProxyInstance(INetworkActions.class.getClassLoader(),
- new Class[] { INetworkActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
+ if (actions instanceof NetworkActions) {
+ ((NetworkActions) actions).sendWakeOnLanPacket();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of NetworkActions");
}
- throw new IllegalArgumentException("Actions is not an instance of " + NetworkActions.class.getName());
}
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.nuvo.internal;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * The {@link INuvoThingActions} defines the interface for all thing actions supported by the binding.
- * These methods, parameters, and return types are explained in {@link NuvoThingActions}.
- *
- * @author Michael Lobstein - Initial contribution
- */
-@NonNullByDefault
-public interface INuvoThingActions {
-
- void sendNuvoCommand(String rawCommand);
-}
*/
package org.openhab.binding.nuvo.internal;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.nuvo.internal.handler.NuvoHandler;
* Some automation actions to be used with a {@link NuvoThingActions}
*
* @author Michael Lobstein - initial contribution
- *
*/
@ThingActionsScope(name = "nuvo")
@NonNullByDefault
-public class NuvoThingActions implements ThingActions, INuvoThingActions {
+public class NuvoThingActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(NuvoThingActions.class);
private @Nullable NuvoHandler handler;
- @RuleAction(label = "sendNuvoCommand", description = "Action that sends raw command to the amplifer")
+ @RuleAction(label = "send a raw command", description = "Send a raw command to the amplifier.")
public void sendNuvoCommand(@ActionInput(name = "sendNuvoCommand") String rawCommand) {
NuvoHandler localHandler = handler;
if (localHandler != null) {
}
/** Static alias to support the old DSL rules engine and make the action available there. */
- public static void sendNuvoCommand(@Nullable ThingActions actions, String rawCommand)
- throws IllegalArgumentException {
- invokeMethodOf(actions).sendNuvoCommand(rawCommand);
+ public static void sendNuvoCommand(@Nullable ThingActions actions, String rawCommand) {
+ if (actions instanceof NuvoThingActions) {
+ ((NuvoThingActions) actions).sendNuvoCommand(rawCommand);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of NuvoThingActions");
+ }
}
@Override
@Override
public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- private static INuvoThingActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(NuvoThingActions.class.getName())) {
- if (actions instanceof NuvoThingActions) {
- return (INuvoThingActions) actions;
- } else {
- return (INuvoThingActions) Proxy.newProxyInstance(INuvoThingActions.class.getClassLoader(),
- new Class[] { INuvoThingActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of NuvoThingActions");
+ return handler;
}
}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.onkyo.internal.handler.OnkyoHandler;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
- * The {@link OnkyoThingActions} defines the interface for all thing actions supported by the binding.
+ * Some automation actions to be used with a {@link OnkyoThingActions}
*
- * @author Laurent Garnier - initial contribution
+ * @author David Masshardt - initial contribution
*/
+@ThingActionsScope(name = "onkyo")
@NonNullByDefault
-public interface OnkyoThingActions {
+public class OnkyoThingActions implements ThingActions {
- public void sendRawCommand(@Nullable String command, @Nullable String value);
+ private final Logger logger = LoggerFactory.getLogger(OnkyoThingActions.class);
+
+ private @Nullable OnkyoHandler handler;
+
+ @SuppressWarnings("null")
+ @RuleAction(label = "send a raw command", description = "Send a raw command to the receiver.")
+ public void sendRawCommand(@ActionInput(name = "command") @Nullable String command,
+ @ActionInput(name = "command") @Nullable String value) {
+ logger.debug("sendRawCommand called with raw command: {} value: {}", command, value);
+ if (handler == null) {
+ logger.warn("Onkyo Action service ThingHandler is null!");
+ return;
+ }
+ handler.sendRawCommand(command, value);
+ }
+
+ public static void sendRawCommand(@Nullable ThingActions actions, @Nullable String command,
+ @Nullable String value) {
+ if (actions instanceof OnkyoThingActions) {
+ ((OnkyoThingActions) actions).sendRawCommand(command, value);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of OnkyoThingActions");
+ }
+ }
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ if (handler instanceof OnkyoHandler) {
+ this.handler = (OnkyoHandler) handler;
+ }
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.onkyo.internal.automation.modules;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.onkyo.internal.handler.OnkyoHandler;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Some automation actions to be used with a {@link OnkyoThingActionsService}
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof OnkyoThingActionsService</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link OnkyoThingActionsService} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
- *
- * @author David Masshardt - initial contribution
- *
- */
-@ThingActionsScope(name = "onkyo")
-@NonNullByDefault
-public class OnkyoThingActionsService implements ThingActions, OnkyoThingActions {
-
- private final Logger logger = LoggerFactory.getLogger(OnkyoThingActionsService.class);
-
- private @Nullable OnkyoHandler handler;
-
- @Override
- @SuppressWarnings("null")
- @RuleAction(label = "Onkyo sendRawCommand", description = "Action that sends raw command to the receiver")
- public void sendRawCommand(@ActionInput(name = "command") @Nullable String command,
- @ActionInput(name = "command") @Nullable String value) {
- logger.debug("sendRawCommand called with raw command: {} value: {}", command, value);
- if (handler == null) {
- logger.warn("Onkyo Action service ThingHandler is null!");
- return;
- }
- handler.sendRawCommand(command, value);
- }
-
- public static void sendRawCommand(@Nullable ThingActions actions, @Nullable String command,
- @Nullable String value) {
- invokeMethodOf(actions).sendRawCommand(command, value);
- }
-
- private static OnkyoThingActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(OnkyoThingActionsService.class.getName())) {
- if (actions instanceof OnkyoThingActions) {
- return (OnkyoThingActions) actions;
- } else {
- return (OnkyoThingActions) Proxy.newProxyInstance(OnkyoThingActions.class.getClassLoader(),
- new Class[] { OnkyoThingActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of OnkyoThingActionsService");
- }
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- if (handler instanceof OnkyoHandler) {
- this.handler = (OnkyoHandler) handler;
- }
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-}
import org.openhab.binding.onkyo.internal.OnkyoEventListener;
import org.openhab.binding.onkyo.internal.OnkyoStateDescriptionProvider;
import org.openhab.binding.onkyo.internal.ServiceType;
-import org.openhab.binding.onkyo.internal.automation.modules.OnkyoThingActionsService;
+import org.openhab.binding.onkyo.internal.automation.modules.OnkyoThingActions;
import org.openhab.binding.onkyo.internal.config.OnkyoDeviceConfiguration;
import org.openhab.binding.onkyo.internal.eiscp.EiscpCommand;
import org.openhab.binding.onkyo.internal.eiscp.EiscpMessage;
@Override
public Collection<Class<? extends ThingHandlerService>> getServices() {
- return Collections.singletonList(OnkyoThingActionsService.class);
+ return Collections.singletonList(OnkyoThingActions.class);
}
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.pushbullet.internal.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link IPushbulletActions} interface defines rule actions for sending notifications
- *
- * @author Laurent Garnier - Initial contribution
- */
-@NonNullByDefault
-public interface IPushbulletActions {
-
- public Boolean sendPushbulletNote(@Nullable String recipient, @Nullable String title, @Nullable String message);
-
- public Boolean sendPushbulletNote(@Nullable String recipient, @Nullable String message);
-}
*/
package org.openhab.binding.pushbullet.internal.action;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.pushbullet.internal.handler.PushbulletHandler;
/**
* The {@link PushbulletActions} class defines rule actions for sending notifications
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof PushbulletActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link PushbulletActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
*
* @author Hakan Tandogan - Initial contribution
*/
@ThingActionsScope(name = "pushbullet")
@NonNullByDefault
-public class PushbulletActions implements ThingActions, IPushbulletActions {
+public class PushbulletActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(PushbulletActions.class);
@Override
public @Nullable ThingHandler getThingHandler() {
- return this.handler;
+ return handler;
}
- @Override
@RuleAction(label = "@text/actionSendPushbulletNoteLabel", description = "@text/actionSendPushbulletNoteDesc")
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendPushbulletNote(
@ActionInput(name = "recipient", label = "@text/actionSendPushbulletNoteInputRecipientLabel", description = "@text/actionSendPushbulletNoteInputRecipientDesc") @Nullable String recipient,
@ActionInput(name = "message", label = "@text/actionSendPushbulletNoteInputMessageLabel", description = "@text/actionSendPushbulletNoteInputMessageDesc") @Nullable String message) {
logger.trace("sendPushbulletNote '{}', '{}', '{}'", recipient, title, message);
- // Use local variable so the SAT check can do proper flow analysis
PushbulletHandler localHandler = handler;
-
if (localHandler == null) {
logger.warn("Pushbullet service Handler is null!");
return false;
public static boolean sendPushbulletNote(@Nullable ThingActions actions, @Nullable String recipient,
@Nullable String title, @Nullable String message) {
- return invokeMethodOf(actions).sendPushbulletNote(recipient, title, message);
+ if (actions instanceof PushbulletActions) {
+ return ((PushbulletActions) actions).sendPushbulletNote(recipient, title, message);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of PushbulletActions");
+ }
}
- @Override
@RuleAction(label = "@text/actionSendPushbulletNoteLabel", description = "@text/actionSendPushbulletNoteDesc")
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendPushbulletNote(
@ActionInput(name = "recipient", label = "@text/actionSendPushbulletNoteInputRecipientLabel", description = "@text/actionSendPushbulletNoteInputRecipientDesc") @Nullable String recipient,
@ActionInput(name = "message", label = "@text/actionSendPushbulletNoteInputMessageLabel", description = "@text/actionSendPushbulletNoteInputMessageDesc") @Nullable String message) {
logger.trace("sendPushbulletNote '{}', '{}'", recipient, message);
- // Use local variable so the SAT check can do proper flow analysis
PushbulletHandler localHandler = handler;
-
if (localHandler == null) {
logger.warn("Pushbullet service Handler is null!");
return false;
public static boolean sendPushbulletNote(@Nullable ThingActions actions, @Nullable String recipient,
@Nullable String message) {
- return invokeMethodOf(actions).sendPushbulletNote(recipient, message);
- }
-
- private static IPushbulletActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(PushbulletActions.class.getName())) {
- if (actions instanceof IPushbulletActions) {
- return (IPushbulletActions) actions;
- } else {
- return (IPushbulletActions) Proxy.newProxyInstance(IPushbulletActions.class.getClassLoader(),
- new Class[] { IPushbulletActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
+ if (actions instanceof PushbulletActions) {
+ return ((PushbulletActions) actions).sendPushbulletNote(recipient, message);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of PushbulletActions");
}
- throw new IllegalArgumentException("Actions is not an instance of PushbulletActions");
}
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.radiothermostat.internal;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link IRadioThermostatThingActions} defines the interface for all thing actions supported by the binding.
- * These methods, parameters, and return types are explained in {@link RadioThermostatThingActions}.
- *
- * @author Michael Lobstein - Initial contribution
- */
-@NonNullByDefault
-public interface IRadioThermostatThingActions {
-
- void sendRawCommand(@Nullable String rawCommand);
-}
*/
package org.openhab.binding.radiothermostat.internal;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.radiothermostat.internal.handler.RadioThermostatHandler;
* Some automation actions to be used with a {@link RadioThermostatThingActions}
*
* @author Michael Lobstein - initial contribution
- *
*/
@ThingActionsScope(name = "radiothermostat")
@NonNullByDefault
-public class RadioThermostatThingActions implements ThingActions, IRadioThermostatThingActions {
+public class RadioThermostatThingActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(RadioThermostatThingActions.class);
private @Nullable RadioThermostatHandler handler;
- @Override
- @RuleAction(label = "sendRawCommand", description = "Action that sends raw command to the thermostat")
+ @RuleAction(label = "send a raw command", description = "Send a raw command to the thermostat.")
public void sendRawCommand(@ActionInput(name = "sendRawCommand") @Nullable String rawCommand) {
- RadioThermostatHandler localHandler = handler;
if (rawCommand == null) {
logger.warn("sendRawCommand called with null command, ignoring");
return;
}
+ RadioThermostatHandler localHandler = handler;
if (localHandler != null) {
localHandler.handleRawCommand(rawCommand);
logger.debug("sendRawCommand called with raw command: {}", rawCommand);
}
/** Static alias to support the old DSL rules engine and make the action available there. */
- public static void sendRawCommand(@Nullable ThingActions actions, @Nullable String rawCommand)
- throws IllegalArgumentException {
- invokeMethodOf(actions).sendRawCommand(rawCommand);
+ public static void sendRawCommand(@Nullable ThingActions actions, @Nullable String rawCommand) {
+ if (actions instanceof RadioThermostatThingActions) {
+ ((RadioThermostatThingActions) actions).sendRawCommand(rawCommand);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of RadioThermostatThingActions");
+ }
}
@Override
@Override
public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- private static IRadioThermostatThingActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(RadioThermostatThingActions.class.getName())) {
- if (actions instanceof RadioThermostatThingActions) {
- return (IRadioThermostatThingActions) actions;
- } else {
- return (IRadioThermostatThingActions) Proxy.newProxyInstance(
- IRadioThermostatThingActions.class.getClassLoader(),
- new Class[] { IRadioThermostatThingActions.class },
- (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of RadioThermostatThingActions");
+ return handler;
}
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.satel.action;
-
-import java.util.Map;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Automation action handler interface for reading Satel event log.
- *
- * @author Krzysztof Goworek - Initial contribution
- */
-@NonNullByDefault
-public interface ISatelEventLogActions {
-
- public Map<String, Object> readEvent(@Nullable Number index);
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.satel.action;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.satel.internal.handler.SatelEventLogHandler;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.ActionOutput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Automation action handler service for reading Satel event log.
- *
- * @author Krzysztof Goworek - Initial contribution
- * @see SatelEventLogHandler
- */
-@ThingActionsScope(name = "satel")
-@NonNullByDefault
-public class SatelEventLogActions implements ThingActions, ISatelEventLogActions {
-
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- private @Nullable SatelEventLogHandler handler;
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- if (handler instanceof SatelEventLogHandler) {
- this.handler = (SatelEventLogHandler) handler;
- }
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return handler;
- }
-
- @Override
- @RuleAction(label = "@text/actionReadEventLabel", description = "@text/actionReadEventDesc")
- public @ActionOutput(name = "index", type = "java.lang.Integer", label = "@text/actionOutputIndexLabel", description = "@text/actionOutputIndexDesc") @ActionOutput(name = "prev_index", type = "java.lang.Integer", label = "@text/actionOutputPrevIndexLabel", description = "@text/actionOutputPrevIndexDesc") @ActionOutput(name = "timestamp", type = "java.time.ZonedDateTime", label = "@text/actionOutputTimestampLabel", description = "@text/actionOutputTimestampDesc") @ActionOutput(name = "description", type = "java.lang.String", label = "@text/actionOutputDescriptionLabel", description = "@text/actionOutputDescriptionDesc") @ActionOutput(name = "details", type = "java.lang.String", label = "@text/actionOutputDetailsLabel", description = "@text/actionOutputDetailsDesc") Map<String, Object> readEvent(
- @ActionInput(name = "index", label = "@text/actionInputIndexLabel", description = "@text/actionInputIndexDesc") @Nullable Number index) {
- logger.debug("satel.readEvent called with input: index={}", index);
-
- Map<String, Object> result = new HashMap<>();
- if (handler != null) {
- handler.readEvent(index == null ? -1 : index.intValue()).ifPresent(event -> {
- result.put("index", event.getIndex());
- result.put("prev_index", event.getPrevIndex());
- result.put("timestamp", event.getTimestamp());
- result.put("description", event.getDescription());
- result.put("details", event.getDetails());
- });
- }
- return result;
- }
-
- public static Map<String, Object> readEvent(@Nullable ThingActions actions, @Nullable Number index) {
- return invokeMethodOf(actions).readEvent(index);
- }
-
- private static ISatelEventLogActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- } else if (actions instanceof ISatelEventLogActions) {
- return (ISatelEventLogActions) actions;
- } else if (actions.getClass().getName().equals(SatelEventLogActions.class.getName())) {
- return (ISatelEventLogActions) Proxy.newProxyInstance(ISatelEventLogActions.class.getClassLoader(),
- new Class[] { ISatelEventLogActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- throw new IllegalArgumentException("actions is not an instance of ISatelEventLogActions");
- }
-}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.satel.internal.action;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.satel.internal.handler.SatelEventLogHandler;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.ActionOutput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Automation action handler service for reading Satel event log.
+ *
+ * @author Krzysztof Goworek - Initial contribution
+ * @see SatelEventLogHandler
+ */
+@ThingActionsScope(name = "satel")
+@NonNullByDefault
+public class SatelEventLogActions implements ThingActions {
+
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
+ private @Nullable SatelEventLogHandler handler;
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ if (handler instanceof SatelEventLogHandler) {
+ this.handler = (SatelEventLogHandler) handler;
+ }
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+
+ @RuleAction(label = "@text/actionReadEventLabel", description = "@text/actionReadEventDesc")
+ public @ActionOutput(name = "index", type = "java.lang.Integer", label = "@text/actionOutputIndexLabel", description = "@text/actionOutputIndexDesc") @ActionOutput(name = "prev_index", type = "java.lang.Integer", label = "@text/actionOutputPrevIndexLabel", description = "@text/actionOutputPrevIndexDesc") @ActionOutput(name = "timestamp", type = "java.time.ZonedDateTime", label = "@text/actionOutputTimestampLabel", description = "@text/actionOutputTimestampDesc") @ActionOutput(name = "description", type = "java.lang.String", label = "@text/actionOutputDescriptionLabel", description = "@text/actionOutputDescriptionDesc") @ActionOutput(name = "details", type = "java.lang.String", label = "@text/actionOutputDetailsLabel", description = "@text/actionOutputDetailsDesc") Map<String, Object> readEvent(
+ @ActionInput(name = "index", label = "@text/actionInputIndexLabel", description = "@text/actionInputIndexDesc") @Nullable Number index) {
+ logger.debug("satel.readEvent called with input: index={}", index);
+
+ Map<String, Object> result = new HashMap<>();
+ if (handler != null) {
+ handler.readEvent(index == null ? -1 : index.intValue()).ifPresent(event -> {
+ result.put("index", event.getIndex());
+ result.put("prev_index", event.getPrevIndex());
+ result.put("timestamp", event.getTimestamp());
+ result.put("description", event.getDescription());
+ result.put("details", event.getDetails());
+ });
+ }
+ return result;
+ }
+
+ public static Map<String, Object> readEvent(@Nullable ThingActions actions, @Nullable Number index) {
+ if (actions instanceof SatelEventLogActions) {
+ return ((SatelEventLogActions) actions).readEvent(index);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of SatelEventLogActions");
+ }
+ }
+}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.satel.action.SatelEventLogActions;
+import org.openhab.binding.satel.internal.action.SatelEventLogActions;
import org.openhab.binding.satel.internal.command.ReadDeviceInfoCommand;
import org.openhab.binding.satel.internal.command.ReadDeviceInfoCommand.DeviceType;
import org.openhab.binding.satel.internal.command.ReadEventCommand;
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.telegram.bot;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Provides the actions for the Telegram API.
- *
- * @author Laurent Garnier - Initial contribution
- */
-@NonNullByDefault
-public interface ITelegramActions {
-
- public boolean sendTelegramAnswer(@Nullable Long chatId, @Nullable String replyId, @Nullable String message);
-
- public boolean sendTelegramAnswer(@Nullable String replyId, @Nullable String message);
-
- public boolean sendTelegram(@Nullable Long chatId, @Nullable String message);
-
- public boolean sendTelegram(@Nullable String message);
-
- public boolean sendTelegramQuery(@Nullable Long chatId, @Nullable String message, @Nullable String replyId,
- @Nullable String... buttons);
-
- public boolean sendTelegramQuery(@Nullable String message, @Nullable String replyId, @Nullable String... buttons);
-
- public boolean sendTelegram(@Nullable Long chatId, @Nullable String message, @Nullable Object... args);
-
- public boolean sendTelegram(@Nullable String message, @Nullable Object... args);
-
- public boolean sendTelegramPhoto(@Nullable Long chatId, @Nullable String photoURL, @Nullable String caption,
- @Nullable String username, @Nullable String password);
-
- public boolean sendTelegramPhoto(@Nullable String photoURL, @Nullable String caption, @Nullable String username,
- @Nullable String password);
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.telegram.bot;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Paths;
-import java.util.Base64;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.apache.commons.io.IOUtils;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.api.Authentication;
-import org.eclipse.jetty.client.api.AuthenticationStore;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpMethod;
-import org.eclipse.jetty.util.B64Code;
-import org.openhab.binding.telegram.internal.TelegramHandler;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.pengrad.telegrambot.model.request.InlineKeyboardButton;
-import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup;
-import com.pengrad.telegrambot.request.AnswerCallbackQuery;
-import com.pengrad.telegrambot.request.EditMessageReplyMarkup;
-import com.pengrad.telegrambot.request.SendMessage;
-import com.pengrad.telegrambot.request.SendPhoto;
-import com.pengrad.telegrambot.response.BaseResponse;
-import com.pengrad.telegrambot.response.SendResponse;
-
-/**
- * Provides the actions for the Telegram API.
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof TelegramActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link TelegramActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
- *
- * @author Alexander Krasnogolowy - Initial contribution
- *
- */
-@ThingActionsScope(name = "telegram")
-@NonNullByDefault
-public class TelegramActions implements ThingActions, ITelegramActions {
- private final Logger logger = LoggerFactory.getLogger(TelegramActions.class);
- private @Nullable TelegramHandler handler;
-
- private boolean evaluateResponse(@Nullable BaseResponse response) {
- if (response != null && !response.isOk()) {
- logger.warn("Failed to send telegram message: {}", response.description());
- return false;
- }
- return true;
- }
-
- @NonNullByDefault
- private static class BasicResult implements Authentication.Result {
-
- private final HttpHeader header;
- private final URI uri;
- private final String value;
-
- public BasicResult(HttpHeader header, URI uri, String value) {
- this.header = header;
- this.uri = uri;
- this.value = value;
- }
-
- @Override
- public URI getURI() {
- return this.uri;
- }
-
- @Override
- public void apply(@Nullable Request request) {
- if (request != null) {
- request.header(this.header, this.value);
- }
- }
-
- @Override
- public String toString() {
- return String.format("Basic authentication result for %s", this.uri);
- }
- }
-
- @Override
- @RuleAction(label = "Telegram answer", description = "Sends a Telegram answer via Telegram API")
- public boolean sendTelegramAnswer(@ActionInput(name = "chatId") @Nullable Long chatId,
- @ActionInput(name = "replyId") @Nullable String replyId,
- @ActionInput(name = "message") @Nullable String message) {
- if (replyId == null) {
- logger.warn("ReplyId not defined; action skipped.");
- return false;
- }
- if (chatId == null) {
- logger.warn("chatId not defined; action skipped.");
- return false;
- }
- TelegramHandler localHandler = handler;
- if (localHandler != null) {
- String callbackId = localHandler.getCallbackId(chatId, replyId);
- if (callbackId != null) {
- AnswerCallbackQuery answerCallbackQuery = new AnswerCallbackQuery(
- localHandler.getCallbackId(chatId, replyId));
- logger.debug("AnswerCallbackQuery for chatId {} and replyId {} is the callbackId {}", chatId, replyId,
- localHandler.getCallbackId(chatId, replyId));
- // we could directly set the text here, but this
- // doesn't result in a real message only in a
- // little popup or in an alert, so the only purpose
- // is to stop the progress bar on client side
- if (!evaluateResponse(localHandler.execute(answerCallbackQuery))) {
- return false;
- }
- }
- Integer messageId = localHandler.removeMessageId(chatId, replyId);
- logger.debug("remove messageId {} for chatId {} and replyId {}", messageId, chatId, replyId);
-
- EditMessageReplyMarkup editReplyMarkup = new EditMessageReplyMarkup(chatId, messageId.intValue())
- .replyMarkup(new InlineKeyboardMarkup(new InlineKeyboardButton[0]));// remove reply markup from
- // old message
- if (!evaluateResponse(localHandler.execute(editReplyMarkup))) {
- return false;
- }
- return message != null ? sendTelegram(chatId, message) : true;
- }
- return false;
- }
-
- @Override
- @RuleAction(label = "Telegram answer", description = "Sends a Telegram answer via Telegram API")
- public boolean sendTelegramAnswer(@ActionInput(name = "replyId") @Nullable String replyId,
- @ActionInput(name = "message") @Nullable String message) {
- TelegramHandler localHandler = handler;
- if (localHandler != null) {
- for (Long chatId : localHandler.getReceiverChatIds()) {
- if (!sendTelegramAnswer(chatId, replyId, message)) {
- return false;
- }
- }
- }
- return true;
- }
-
- @Override
- @RuleAction(label = "Telegram message", description = "Sends a Telegram via Telegram API")
- public boolean sendTelegram(@ActionInput(name = "chatId") @Nullable Long chatId,
- @ActionInput(name = "message") @Nullable String message) {
- return sendTelegramGeneral(chatId, message, (String) null);
- }
-
- @Override
- @RuleAction(label = "Telegram message", description = "Sends a Telegram via Telegram API")
- public boolean sendTelegram(@ActionInput(name = "message") @Nullable String message) {
- TelegramHandler localHandler = handler;
- if (localHandler != null) {
- for (Long chatId : localHandler.getReceiverChatIds()) {
- if (!sendTelegram(chatId, message)) {
- return false;
- }
- }
- }
- return true;
- }
-
- @Override
- @RuleAction(label = "Telegram message", description = "Sends a Telegram via Telegram API")
- public boolean sendTelegramQuery(@ActionInput(name = "chatId") @Nullable Long chatId,
- @ActionInput(name = "message") @Nullable String message,
- @ActionInput(name = "replyId") @Nullable String replyId,
- @ActionInput(name = "buttons") @Nullable String... buttons) {
- return sendTelegramGeneral(chatId, message, replyId, buttons);
- }
-
- @Override
- @RuleAction(label = "Telegram message", description = "Sends a Telegram via Telegram API")
- public boolean sendTelegramQuery(@ActionInput(name = "message") @Nullable String message,
- @ActionInput(name = "replyId") @Nullable String replyId,
- @ActionInput(name = "buttons") @Nullable String... buttons) {
- TelegramHandler localHandler = handler;
- if (localHandler != null) {
- for (Long chatId : localHandler.getReceiverChatIds()) {
- if (!sendTelegramQuery(chatId, message, replyId, buttons)) {
- return false;
- }
- }
- }
- return true;
- }
-
- private boolean sendTelegramGeneral(@ActionInput(name = "chatId") @Nullable Long chatId, @Nullable String message,
- @Nullable String replyId, @Nullable String... buttons) {
- if (message == null) {
- logger.warn("Message not defined; action skipped.");
- return false;
- }
- if (chatId == null) {
- logger.warn("chatId not defined; action skipped.");
- return false;
- }
- TelegramHandler localHandler = handler;
- if (localHandler != null) {
- SendMessage sendMessage = new SendMessage(chatId, message);
- if (localHandler.getParseMode() != null) {
- sendMessage.parseMode(localHandler.getParseMode());
- }
- if (replyId != null) {
- if (!replyId.contains(" ")) {
- if (buttons.length > 0) {
- InlineKeyboardButton[][] keyboard2D = new InlineKeyboardButton[1][];
- InlineKeyboardButton[] keyboard = new InlineKeyboardButton[buttons.length];
- keyboard2D[0] = keyboard;
- for (int i = 0; i < buttons.length; i++) {
- keyboard[i] = new InlineKeyboardButton(buttons[i]).callbackData(replyId + " " + buttons[i]);
- }
- InlineKeyboardMarkup keyBoardMarkup = new InlineKeyboardMarkup(keyboard2D);
- sendMessage.replyMarkup(keyBoardMarkup);
- } else {
- logger.warn(
- "The replyId {} for message {} is given, but no buttons are defined. ReplyMarkup will be ignored.",
- replyId, message);
- }
- } else {
- logger.warn("replyId {} must not contain spaces. ReplyMarkup will be ignored.", replyId);
- }
- }
- SendResponse retMessage = localHandler.execute(sendMessage);
- if (!evaluateResponse(retMessage)) {
- return false;
- }
- if (replyId != null && retMessage != null) {
- logger.debug("Adding chatId {}, replyId {} and messageId {}", chatId, replyId,
- retMessage.message().messageId());
- localHandler.addMessageId(chatId, replyId, retMessage.message().messageId());
- }
- return true;
- }
- return false;
- }
-
- @Override
- @RuleAction(label = "Telegram message", description = "Sends a Telegram via Telegram API")
- public boolean sendTelegram(@ActionInput(name = "chatId") @Nullable Long chatId,
- @ActionInput(name = "message") @Nullable String message,
- @ActionInput(name = "args") @Nullable Object... args) {
- return sendTelegram(chatId, String.format(message, args));
- }
-
- @Override
- @RuleAction(label = "Telegram message", description = "Sends a Telegram via Telegram API")
- public boolean sendTelegram(@ActionInput(name = "message") @Nullable String message,
- @ActionInput(name = "args") @Nullable Object... args) {
- TelegramHandler localHandler = handler;
- if (localHandler != null) {
- for (Long chatId : localHandler.getReceiverChatIds()) {
- if (!sendTelegram(chatId, message, args)) {
- return false;
- }
- }
- }
- return true;
- }
-
- @RuleAction(label = "Telegram photo", description = "Sends a Picture via Telegram API")
- public boolean sendTelegramPhoto(@ActionInput(name = "chatId") @Nullable Long chatId,
- @ActionInput(name = "photoURL") @Nullable String photoURL,
- @ActionInput(name = "caption") @Nullable String caption) {
- return sendTelegramPhoto(chatId, photoURL, caption, null, null);
- }
-
- @Override
- @RuleAction(label = "Telegram photo", description = "Sends a Picture via Telegram API")
- public boolean sendTelegramPhoto(@ActionInput(name = "chatId") @Nullable Long chatId,
- @ActionInput(name = "photoURL") @Nullable String photoURL,
- @ActionInput(name = "caption") @Nullable String caption,
- @ActionInput(name = "username") @Nullable String username,
- @ActionInput(name = "password") @Nullable String password) {
- if (photoURL == null) {
- logger.warn("Photo URL not defined; unable to retrieve photo for sending.");
- return false;
- }
- if (chatId == null) {
- logger.warn("chatId not defined; action skipped.");
- return false;
- }
-
- TelegramHandler localHandler = handler;
- if (localHandler != null) {
- final SendPhoto sendPhoto;
-
- if (photoURL.toLowerCase().startsWith("http")) {
- // load image from url
- logger.debug("Photo URL provided.");
- HttpClient client = localHandler.getClient();
- if (client == null) {
- return false;
- }
- Request request = client.newRequest(photoURL).method(HttpMethod.GET).timeout(30, TimeUnit.SECONDS);
- if (username != null && password != null) {
- AuthenticationStore auth = client.getAuthenticationStore();
- URI uri = URI.create(photoURL);
- auth.addAuthenticationResult(new BasicResult(HttpHeader.AUTHORIZATION, uri,
- "Basic " + B64Code.encode(username + ":" + password, StandardCharsets.ISO_8859_1)));
- }
- try {
- ContentResponse contentResponse = request.send();
- if (contentResponse.getStatus() == 200) {
- byte[] fileContent = contentResponse.getContent();
- sendPhoto = new SendPhoto(chatId, fileContent);
- } else {
- logger.warn("Download from {} failed with status: {}", photoURL, contentResponse.getStatus());
- return false;
- }
- } catch (InterruptedException | TimeoutException | ExecutionException e) {
- logger.warn("Download from {} failed with exception: {}", photoURL, e.getMessage());
- return false;
- }
- } else if (photoURL.toLowerCase().startsWith("file")) {
- // Load image from local file system
- logger.debug("Read file from local file system: {}", photoURL);
- try {
- URL url = new URL(photoURL);
- sendPhoto = new SendPhoto(chatId, Paths.get(url.getPath()).toFile());
- } catch (MalformedURLException e) {
- logger.warn("Malformed URL: {}", photoURL);
- return false;
- }
- } else {
- // Load image from provided base64 image
- logger.debug("Photo base64 provided; converting to binary.");
- final String photoB64Data;
- if (photoURL.startsWith("data:")) { // support data URI scheme
- String[] photoURLParts = photoURL.split(",");
- if (photoURLParts.length > 1) {
- photoB64Data = photoURLParts[1];
- } else {
- logger.warn("The provided base64 string is not a valid data URI scheme");
- return false;
- }
- } else {
- photoB64Data = photoURL;
- }
- InputStream is = Base64.getDecoder()
- .wrap(new ByteArrayInputStream(photoB64Data.getBytes(StandardCharsets.UTF_8)));
- try {
- byte[] photoBytes = IOUtils.toByteArray(is);
- sendPhoto = new SendPhoto(chatId, photoBytes);
- } catch (IOException e) {
- logger.warn("Malformed base64 string: {}", e.getMessage());
- return false;
- }
- }
- sendPhoto.caption(caption);
- if (localHandler.getParseMode() != null) {
- sendPhoto.parseMode(localHandler.getParseMode());
- }
- return evaluateResponse(localHandler.execute(sendPhoto));
- }
- return false;
- }
-
- @Override
- @RuleAction(label = "Telegram photo", description = "Sends a Picture via Telegram API")
- public boolean sendTelegramPhoto(@ActionInput(name = "photoURL") @Nullable String photoURL,
- @ActionInput(name = "caption") @Nullable String caption,
- @ActionInput(name = "username") @Nullable String username,
- @ActionInput(name = "password") @Nullable String password) {
- TelegramHandler localHandler = handler;
- if (localHandler != null) {
- for (Long chatId : localHandler.getReceiverChatIds()) {
- if (!sendTelegramPhoto(chatId, photoURL, caption, username, password)) {
- return false;
- }
- }
- }
- return true;
- }
-
- @RuleAction(label = "Telegram photo", description = "Sends a Picture via Telegram API")
- public boolean sendTelegramPhoto(@ActionInput(name = "photoURL") @Nullable String photoURL,
- @ActionInput(name = "caption") @Nullable String caption) {
- return sendTelegramPhoto(photoURL, caption, null, null);
- }
-
- // legacy delegate methods
- /* APIs without chatId parameter */
- public static boolean sendTelegram(@Nullable ThingActions actions, @Nullable String format,
- @Nullable Object... args) {
- return invokeMethodOf(actions).sendTelegram(format, args);
- }
-
- public static boolean sendTelegramQuery(@Nullable ThingActions actions, @Nullable String message,
- @Nullable String replyId, @Nullable String... buttons) {
- return invokeMethodOf(actions).sendTelegramQuery(message, replyId, buttons);
- }
-
- public static boolean sendTelegramPhoto(@Nullable ThingActions actions, @Nullable String photoURL,
- @Nullable String caption) {
- return invokeMethodOf(actions).sendTelegramPhoto(photoURL, caption, null, null);
- }
-
- public static boolean sendTelegramPhoto(@Nullable ThingActions actions, @Nullable String photoURL,
- @Nullable String caption, @Nullable String username, @Nullable String password) {
- return invokeMethodOf(actions).sendTelegramPhoto(photoURL, caption, username, password);
- }
-
- public static boolean sendTelegramAnswer(@Nullable ThingActions actions, @Nullable String replyId,
- @Nullable String message) {
- return invokeMethodOf(actions).sendTelegramAnswer(replyId, message);
- }
-
- /* APIs with chatId parameter */
-
- public static boolean sendTelegram(@Nullable ThingActions actions, @Nullable Long chatId, @Nullable String format,
- @Nullable Object... args) {
- return invokeMethodOf(actions).sendTelegram(chatId, format, args);
- }
-
- public static boolean sendTelegramQuery(@Nullable ThingActions actions, @Nullable Long chatId,
- @Nullable String message, @Nullable String replyId, @Nullable String... buttons) {
- return invokeMethodOf(actions).sendTelegramQuery(chatId, message, replyId, buttons);
- }
-
- public static boolean sendTelegramPhoto(@Nullable ThingActions actions, @Nullable Long chatId,
- @Nullable String photoURL, @Nullable String caption) {
- return invokeMethodOf(actions).sendTelegramPhoto(chatId, photoURL, caption, null, null);
- }
-
- public static boolean sendTelegramPhoto(@Nullable ThingActions actions, @Nullable Long chatId,
- @Nullable String photoURL, @Nullable String caption, @Nullable String username, @Nullable String password) {
- return invokeMethodOf(actions).sendTelegramPhoto(chatId, photoURL, caption, username, password);
- }
-
- public static boolean sendTelegramAnswer(@Nullable ThingActions actions, @Nullable Long chatId,
- @Nullable String replyId, @Nullable String message) {
- return invokeMethodOf(actions).sendTelegramAnswer(chatId, replyId, message);
- }
-
- public static boolean sendTelegramAnswer(@Nullable ThingActions actions, @Nullable String chatId,
- @Nullable String replyId, @Nullable String message) {
- return invokeMethodOf(actions).sendTelegramAnswer(Long.valueOf(chatId), replyId, message);
- }
-
- private static ITelegramActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(TelegramActions.class.getName())) {
- if (actions instanceof ITelegramActions) {
- return (ITelegramActions) actions;
- } else {
- return (ITelegramActions) Proxy.newProxyInstance(ITelegramActions.class.getClassLoader(),
- new Class[] { ITelegramActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
- }
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- this.handler = (TelegramHandler) handler;
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return handler;
- }
-}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
-import org.openhab.binding.telegram.bot.TelegramActions;
+import org.openhab.binding.telegram.internal.action.TelegramActions;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.ChannelUID;
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.telegram.internal.action;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Paths;
+import java.util.Base64;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.commons.io.IOUtils;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.Authentication;
+import org.eclipse.jetty.client.api.AuthenticationStore;
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.util.B64Code;
+import org.openhab.binding.telegram.internal.TelegramHandler;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.pengrad.telegrambot.model.request.InlineKeyboardButton;
+import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup;
+import com.pengrad.telegrambot.request.AnswerCallbackQuery;
+import com.pengrad.telegrambot.request.EditMessageReplyMarkup;
+import com.pengrad.telegrambot.request.SendMessage;
+import com.pengrad.telegrambot.request.SendPhoto;
+import com.pengrad.telegrambot.response.BaseResponse;
+import com.pengrad.telegrambot.response.SendResponse;
+
+/**
+ * Provides the actions for the Telegram API.
+ *
+ * @author Alexander Krasnogolowy - Initial contribution
+ */
+@ThingActionsScope(name = "telegram")
+@NonNullByDefault
+public class TelegramActions implements ThingActions {
+ private final Logger logger = LoggerFactory.getLogger(TelegramActions.class);
+ private @Nullable TelegramHandler handler;
+
+ private boolean evaluateResponse(@Nullable BaseResponse response) {
+ if (response != null && !response.isOk()) {
+ logger.warn("Failed to send telegram message: {}", response.description());
+ return false;
+ }
+ return true;
+ }
+
+ private static class BasicResult implements Authentication.Result {
+
+ private final HttpHeader header;
+ private final URI uri;
+ private final String value;
+
+ public BasicResult(HttpHeader header, URI uri, String value) {
+ this.header = header;
+ this.uri = uri;
+ this.value = value;
+ }
+
+ @Override
+ public URI getURI() {
+ return this.uri;
+ }
+
+ @Override
+ public void apply(@Nullable Request request) {
+ if (request != null) {
+ request.header(this.header, this.value);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Basic authentication result for %s", this.uri);
+ }
+ }
+
+ @RuleAction(label = "send an answer", description = "Send a Telegram answer using the Telegram API.")
+ public boolean sendTelegramAnswer(@ActionInput(name = "chatId") @Nullable Long chatId,
+ @ActionInput(name = "replyId") @Nullable String replyId,
+ @ActionInput(name = "message") @Nullable String message) {
+ if (replyId == null) {
+ logger.warn("ReplyId not defined; action skipped.");
+ return false;
+ }
+ if (chatId == null) {
+ logger.warn("chatId not defined; action skipped.");
+ return false;
+ }
+ TelegramHandler localHandler = handler;
+ if (localHandler != null) {
+ String callbackId = localHandler.getCallbackId(chatId, replyId);
+ if (callbackId != null) {
+ AnswerCallbackQuery answerCallbackQuery = new AnswerCallbackQuery(
+ localHandler.getCallbackId(chatId, replyId));
+ logger.debug("AnswerCallbackQuery for chatId {} and replyId {} is the callbackId {}", chatId, replyId,
+ localHandler.getCallbackId(chatId, replyId));
+ // we could directly set the text here, but this
+ // doesn't result in a real message only in a
+ // little popup or in an alert, so the only purpose
+ // is to stop the progress bar on client side
+ if (!evaluateResponse(localHandler.execute(answerCallbackQuery))) {
+ return false;
+ }
+ }
+ Integer messageId = localHandler.removeMessageId(chatId, replyId);
+ logger.debug("remove messageId {} for chatId {} and replyId {}", messageId, chatId, replyId);
+
+ EditMessageReplyMarkup editReplyMarkup = new EditMessageReplyMarkup(chatId, messageId.intValue())
+ .replyMarkup(new InlineKeyboardMarkup(new InlineKeyboardButton[0]));// remove reply markup from
+ // old message
+ if (!evaluateResponse(localHandler.execute(editReplyMarkup))) {
+ return false;
+ }
+ return message != null ? sendTelegram(chatId, message) : true;
+ }
+ return false;
+ }
+
+ @RuleAction(label = "send an answer", description = "Send a Telegram answer using the Telegram API.")
+ public boolean sendTelegramAnswer(@ActionInput(name = "replyId") @Nullable String replyId,
+ @ActionInput(name = "message") @Nullable String message) {
+ TelegramHandler localHandler = handler;
+ if (localHandler != null) {
+ for (Long chatId : localHandler.getReceiverChatIds()) {
+ if (!sendTelegramAnswer(chatId, replyId, message)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ @RuleAction(label = "send a message", description = "Send a Telegram message using the Telegram API.")
+ public boolean sendTelegram(@ActionInput(name = "chatId") @Nullable Long chatId,
+ @ActionInput(name = "message") @Nullable String message) {
+ return sendTelegramGeneral(chatId, message, (String) null);
+ }
+
+ @RuleAction(label = "send a message", description = "Send a Telegram message using the Telegram API.")
+ public boolean sendTelegram(@ActionInput(name = "message") @Nullable String message) {
+ TelegramHandler localHandler = handler;
+ if (localHandler != null) {
+ for (Long chatId : localHandler.getReceiverChatIds()) {
+ if (!sendTelegram(chatId, message)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ @RuleAction(label = "send a message", description = "Send a Telegram using the Telegram API.")
+ public boolean sendTelegramQuery(@ActionInput(name = "chatId") @Nullable Long chatId,
+ @ActionInput(name = "message") @Nullable String message,
+ @ActionInput(name = "replyId") @Nullable String replyId,
+ @ActionInput(name = "buttons") @Nullable String... buttons) {
+ return sendTelegramGeneral(chatId, message, replyId, buttons);
+ }
+
+ @RuleAction(label = "send a message", description = "Send a Telegram using the Telegram API.")
+ public boolean sendTelegramQuery(@ActionInput(name = "message") @Nullable String message,
+ @ActionInput(name = "replyId") @Nullable String replyId,
+ @ActionInput(name = "buttons") @Nullable String... buttons) {
+ TelegramHandler localHandler = handler;
+ if (localHandler != null) {
+ for (Long chatId : localHandler.getReceiverChatIds()) {
+ if (!sendTelegramQuery(chatId, message, replyId, buttons)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean sendTelegramGeneral(@ActionInput(name = "chatId") @Nullable Long chatId, @Nullable String message,
+ @Nullable String replyId, @Nullable String... buttons) {
+ if (message == null) {
+ logger.warn("Message not defined; action skipped.");
+ return false;
+ }
+ if (chatId == null) {
+ logger.warn("chatId not defined; action skipped.");
+ return false;
+ }
+ TelegramHandler localHandler = handler;
+ if (localHandler != null) {
+ SendMessage sendMessage = new SendMessage(chatId, message);
+ if (localHandler.getParseMode() != null) {
+ sendMessage.parseMode(localHandler.getParseMode());
+ }
+ if (replyId != null) {
+ if (!replyId.contains(" ")) {
+ if (buttons.length > 0) {
+ InlineKeyboardButton[][] keyboard2D = new InlineKeyboardButton[1][];
+ InlineKeyboardButton[] keyboard = new InlineKeyboardButton[buttons.length];
+ keyboard2D[0] = keyboard;
+ for (int i = 0; i < buttons.length; i++) {
+ keyboard[i] = new InlineKeyboardButton(buttons[i]).callbackData(replyId + " " + buttons[i]);
+ }
+ InlineKeyboardMarkup keyBoardMarkup = new InlineKeyboardMarkup(keyboard2D);
+ sendMessage.replyMarkup(keyBoardMarkup);
+ } else {
+ logger.warn(
+ "The replyId {} for message {} is given, but no buttons are defined. ReplyMarkup will be ignored.",
+ replyId, message);
+ }
+ } else {
+ logger.warn("replyId {} must not contain spaces. ReplyMarkup will be ignored.", replyId);
+ }
+ }
+ SendResponse retMessage = localHandler.execute(sendMessage);
+ if (!evaluateResponse(retMessage)) {
+ return false;
+ }
+ if (replyId != null && retMessage != null) {
+ logger.debug("Adding chatId {}, replyId {} and messageId {}", chatId, replyId,
+ retMessage.message().messageId());
+ localHandler.addMessageId(chatId, replyId, retMessage.message().messageId());
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @RuleAction(label = "send a message", description = "Send a Telegram using the Telegram API.")
+ public boolean sendTelegram(@ActionInput(name = "chatId") @Nullable Long chatId,
+ @ActionInput(name = "message") @Nullable String message,
+ @ActionInput(name = "args") @Nullable Object... args) {
+ return sendTelegram(chatId, String.format(message, args));
+ }
+
+ @RuleAction(label = "send a message", description = "Send a Telegram using the Telegram API.")
+ public boolean sendTelegram(@ActionInput(name = "message") @Nullable String message,
+ @ActionInput(name = "args") @Nullable Object... args) {
+ TelegramHandler localHandler = handler;
+ if (localHandler != null) {
+ for (Long chatId : localHandler.getReceiverChatIds()) {
+ if (!sendTelegram(chatId, message, args)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ @RuleAction(label = "send a photo", description = "Send a picture using the Telegram API.")
+ public boolean sendTelegramPhoto(@ActionInput(name = "chatId") @Nullable Long chatId,
+ @ActionInput(name = "photoURL") @Nullable String photoURL,
+ @ActionInput(name = "caption") @Nullable String caption) {
+ return sendTelegramPhoto(chatId, photoURL, caption, null, null);
+ }
+
+ @RuleAction(label = "send a photo", description = "Send a picture using the Telegram API.")
+ public boolean sendTelegramPhoto(@ActionInput(name = "chatId") @Nullable Long chatId,
+ @ActionInput(name = "photoURL") @Nullable String photoURL,
+ @ActionInput(name = "caption") @Nullable String caption,
+ @ActionInput(name = "username") @Nullable String username,
+ @ActionInput(name = "password") @Nullable String password) {
+ if (photoURL == null) {
+ logger.warn("Photo URL not defined; unable to retrieve photo for sending.");
+ return false;
+ }
+ if (chatId == null) {
+ logger.warn("chatId not defined; action skipped.");
+ return false;
+ }
+
+ TelegramHandler localHandler = handler;
+ if (localHandler != null) {
+ final SendPhoto sendPhoto;
+
+ if (photoURL.toLowerCase().startsWith("http")) {
+ // load image from url
+ logger.debug("Photo URL provided.");
+ HttpClient client = localHandler.getClient();
+ if (client == null) {
+ return false;
+ }
+ Request request = client.newRequest(photoURL).method(HttpMethod.GET).timeout(30, TimeUnit.SECONDS);
+ if (username != null && password != null) {
+ AuthenticationStore auth = client.getAuthenticationStore();
+ URI uri = URI.create(photoURL);
+ auth.addAuthenticationResult(new BasicResult(HttpHeader.AUTHORIZATION, uri,
+ "Basic " + B64Code.encode(username + ":" + password, StandardCharsets.ISO_8859_1)));
+ }
+ try {
+ ContentResponse contentResponse = request.send();
+ if (contentResponse.getStatus() == 200) {
+ byte[] fileContent = contentResponse.getContent();
+ sendPhoto = new SendPhoto(chatId, fileContent);
+ } else {
+ logger.warn("Download from {} failed with status: {}", photoURL, contentResponse.getStatus());
+ return false;
+ }
+ } catch (InterruptedException | TimeoutException | ExecutionException e) {
+ logger.warn("Download from {} failed with exception: {}", photoURL, e.getMessage());
+ return false;
+ }
+ } else if (photoURL.toLowerCase().startsWith("file")) {
+ // Load image from local file system
+ logger.debug("Read file from local file system: {}", photoURL);
+ try {
+ URL url = new URL(photoURL);
+ sendPhoto = new SendPhoto(chatId, Paths.get(url.getPath()).toFile());
+ } catch (MalformedURLException e) {
+ logger.warn("Malformed URL: {}", photoURL);
+ return false;
+ }
+ } else {
+ // Load image from provided base64 image
+ logger.debug("Photo base64 provided; converting to binary.");
+ final String photoB64Data;
+ if (photoURL.startsWith("data:")) { // support data URI scheme
+ String[] photoURLParts = photoURL.split(",");
+ if (photoURLParts.length > 1) {
+ photoB64Data = photoURLParts[1];
+ } else {
+ logger.warn("The provided base64 string is not a valid data URI scheme");
+ return false;
+ }
+ } else {
+ photoB64Data = photoURL;
+ }
+ InputStream is = Base64.getDecoder()
+ .wrap(new ByteArrayInputStream(photoB64Data.getBytes(StandardCharsets.UTF_8)));
+ try {
+ byte[] photoBytes = IOUtils.toByteArray(is);
+ sendPhoto = new SendPhoto(chatId, photoBytes);
+ } catch (IOException e) {
+ logger.warn("Malformed base64 string: {}", e.getMessage());
+ return false;
+ }
+ }
+ sendPhoto.caption(caption);
+ if (localHandler.getParseMode() != null) {
+ sendPhoto.parseMode(localHandler.getParseMode());
+ }
+ return evaluateResponse(localHandler.execute(sendPhoto));
+ }
+ return false;
+ }
+
+ @RuleAction(label = "send a photo", description = "Send a Picture using the Telegram API.")
+ public boolean sendTelegramPhoto(@ActionInput(name = "photoURL") @Nullable String photoURL,
+ @ActionInput(name = "caption") @Nullable String caption,
+ @ActionInput(name = "username") @Nullable String username,
+ @ActionInput(name = "password") @Nullable String password) {
+ TelegramHandler localHandler = handler;
+ if (localHandler != null) {
+ for (Long chatId : localHandler.getReceiverChatIds()) {
+ if (!sendTelegramPhoto(chatId, photoURL, caption, username, password)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ @RuleAction(label = "send a photo", description = "Send a Picture using the Telegram API.")
+ public boolean sendTelegramPhoto(@ActionInput(name = "photoURL") @Nullable String photoURL,
+ @ActionInput(name = "caption") @Nullable String caption) {
+ return sendTelegramPhoto(photoURL, caption, null, null);
+ }
+
+ // legacy delegate methods
+ /* APIs without chatId parameter */
+ public static boolean sendTelegram(@Nullable ThingActions actions, @Nullable String format,
+ @Nullable Object... args) {
+ if (actions instanceof TelegramActions) {
+ return ((TelegramActions) actions).sendTelegram(format, args);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
+ }
+ }
+
+ public static boolean sendTelegramQuery(@Nullable ThingActions actions, @Nullable String message,
+ @Nullable String replyId, @Nullable String... buttons) {
+ if (actions instanceof TelegramActions) {
+ return ((TelegramActions) actions).sendTelegramQuery(message, replyId, buttons);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
+ }
+ }
+
+ public static boolean sendTelegramPhoto(@Nullable ThingActions actions, @Nullable String photoURL,
+ @Nullable String caption) {
+ if (actions instanceof TelegramActions) {
+ return ((TelegramActions) actions).sendTelegramPhoto(photoURL, caption, null, null);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
+ }
+ }
+
+ public static boolean sendTelegramPhoto(@Nullable ThingActions actions, @Nullable String photoURL,
+ @Nullable String caption, @Nullable String username, @Nullable String password) {
+ if (actions instanceof TelegramActions) {
+ return ((TelegramActions) actions).sendTelegramPhoto(photoURL, caption, username, password);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
+ }
+ }
+
+ public static boolean sendTelegramAnswer(@Nullable ThingActions actions, @Nullable String replyId,
+ @Nullable String message) {
+ if (actions instanceof TelegramActions) {
+ return ((TelegramActions) actions).sendTelegramAnswer(replyId, message);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
+ }
+ }
+
+ /* APIs with chatId parameter */
+
+ public static boolean sendTelegram(@Nullable ThingActions actions, @Nullable Long chatId, @Nullable String format,
+ @Nullable Object... args) {
+ if (actions instanceof TelegramActions) {
+ return ((TelegramActions) actions).sendTelegram(chatId, format, args);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
+ }
+ }
+
+ public static boolean sendTelegramQuery(@Nullable ThingActions actions, @Nullable Long chatId,
+ @Nullable String message, @Nullable String replyId, @Nullable String... buttons) {
+ if (actions instanceof TelegramActions) {
+ return ((TelegramActions) actions).sendTelegramQuery(chatId, message, replyId, buttons);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
+ }
+ }
+
+ public static boolean sendTelegramPhoto(@Nullable ThingActions actions, @Nullable Long chatId,
+ @Nullable String photoURL, @Nullable String caption) {
+ if (actions instanceof TelegramActions) {
+ return ((TelegramActions) actions).sendTelegramPhoto(chatId, photoURL, caption, null, null);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
+ }
+ }
+
+ public static boolean sendTelegramPhoto(@Nullable ThingActions actions, @Nullable Long chatId,
+ @Nullable String photoURL, @Nullable String caption, @Nullable String username, @Nullable String password) {
+ if (actions instanceof TelegramActions) {
+ return ((TelegramActions) actions).sendTelegramPhoto(chatId, photoURL, caption, username, password);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
+ }
+ }
+
+ public static boolean sendTelegramAnswer(@Nullable ThingActions actions, @Nullable Long chatId,
+ @Nullable String replyId, @Nullable String message) {
+ if (actions instanceof TelegramActions) {
+ return ((TelegramActions) actions).sendTelegramAnswer(chatId, replyId, message);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
+ }
+ }
+
+ public static boolean sendTelegramAnswer(@Nullable ThingActions actions, @Nullable String chatId,
+ @Nullable String replyId, @Nullable String message) {
+ if (actions instanceof TelegramActions) {
+ return ((TelegramActions) actions).sendTelegramAnswer(Long.valueOf(chatId), replyId, message);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
+ }
+ }
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ this.handler = (TelegramHandler) handler;
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+}
private @Nullable VehicleHandler handler;
public VolvoOnCallActions() {
- logger.info("Volvo On Call actions service instanciated");
+ logger.debug("Volvo On Call actions service instantiated");
}
@Override
@Override
public @Nullable ThingHandler getThingHandler() {
- return this.handler;
+ return handler;
}
@RuleAction(label = "close the car", description = "Closes the car")
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.xmppclient;
-
-import org.openhab.core.thing.ThingTypeUID;
-
-/**
- * The {@link XMPPClientBindingConstants} class defines common constants, which are
- * used across the whole binding.
- *
- * @author Pavel Gololobov - Initial contribution
- */
-public class XMPPClientBindingConstants {
- private static final String BINDING_ID = "xmppclient";
-
- // List of all Thing Type UIDs
- public static final ThingTypeUID BRIDGE_TYPE_XMPP = new ThingTypeUID(BINDING_ID, "xmppBridge");
- public static final String PUBLISH_TRIGGER_CHANNEL = "publishTrigger";
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.xmppclient.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * This is the automation engine action handler service for the publishXMPP action.
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof XMPPActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link IXMPPActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
- *
- * @author Laurent Garnier - Initial contribution
- */
-@NonNullByDefault
-public interface IXMPPActions {
-
- public void publishXMPP(@Nullable String to, @Nullable String text);
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.xmppclient.action;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.xmppclient.handler.XMPPClientHandler;
-import org.openhab.binding.xmppclient.internal.XMPPClient;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This is the automation engine action handler service for the publishXMPP action.
- * <p>
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof XMPPActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link XMPPActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
- *
- * @author Pavel Gololobov - Initial contribution
- */
-@ThingActionsScope(name = "xmpp")
-@NonNullByDefault
-public class XMPPActions implements ThingActions, IXMPPActions {
- private static final Logger logger = LoggerFactory.getLogger(XMPPActions.class);
- private @Nullable XMPPClientHandler handler;
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- this.handler = (XMPPClientHandler) handler;
- }
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- @Override
- @RuleAction(label = "publishXMPP", description = "Publish to XMPP")
- public void publishXMPP(@ActionInput(name = "to", label = "To", description = "Send to") @Nullable String to,
- @ActionInput(name = "text", label = "Text", description = "Message text") @Nullable String text) {
- XMPPClientHandler clientHandler = handler;
- if (clientHandler == null) {
- logger.warn("XMPP ThingHandler is null");
- return;
- }
-
- XMPPClient connection = clientHandler.getXMPPClient();
- if (connection == null) {
- logger.warn("XMPP ThingHandler connection is null");
- return;
- }
- if ((to == null) || (text == null)) {
- logger.info("Skipping XMPP messaging to {} value {}", to, text);
- return;
- }
- connection.sendMessage(to, text);
- }
-
- public static void publishXMPP(@Nullable ThingActions actions, @Nullable String to, @Nullable String text) {
- invokeMethodOf(actions).publishXMPP(to, text);
- }
-
- private static IXMPPActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(XMPPActions.class.getName())) {
- if (actions instanceof IXMPPActions) {
- return (IXMPPActions) actions;
- } else {
- return (IXMPPActions) Proxy.newProxyInstance(IXMPPActions.class.getClassLoader(),
- new Class[] { IXMPPActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of XMPPActions");
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.xmppclient.handler;
-
-import org.openhab.binding.xmppclient.internal.XMPPClient;
-import org.openhab.core.thing.ChannelUID;
-
-/**
- * Subscribes to a chat and calls {@link AbstractBrokerHandler#triggerChannel(ChannelUID, String)} if a value has been
- * received.
- *
- * @author Pavel Gololobov - Initial contribution
- */
-public class PublishTriggerChannel implements XMPPClientMessageSubscriber {
- private final XMPPClient connection;
- private final PublishTriggerChannelConfig config;
- private final ChannelUID uid;
- private final XMPPClientHandler handler;
-
- PublishTriggerChannel(PublishTriggerChannelConfig config, ChannelUID uid, XMPPClient connection,
- XMPPClientHandler handler) {
- this.config = config;
- this.uid = uid;
- this.connection = connection;
- this.handler = handler;
- }
-
- public void start() {
- connection.subscribe(this);
- }
-
- public void stop() {
- connection.unsubscribe(this);
- }
-
- @Override
- public void processMessage(String from, String payload) {
- // Check condition if exists
- String expectedPayload = config.payload;
- if ((expectedPayload != null) && (!expectedPayload.isEmpty()) && !payload.equals(expectedPayload)) {
- return;
- }
- String eventValue = "";
- if (!config.separator.isEmpty()) {
- eventValue = from + config.separator + payload;
- } else {
- eventValue = payload;
- }
- handler.triggerChannel(uid, eventValue);
- }
-
- @Override
- public String getName() {
- return uid.toString();
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.xmppclient.handler;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Holds the configuration of a {@link PublishTriggerChannel}.
- *
- * @author Pavel Gololobov - Initial contribution
- */
-@NonNullByDefault
-public class PublishTriggerChannelConfig {
- public @Nullable String payload;
- public String separator = "";
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.xmppclient.handler;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link XMPPClientConfiguration} class contains fields mapping thing configuration parameters.
- *
- * @author Pavel Gololobov - Initial contribution
- */
-@NonNullByDefault
-public class XMPPClientConfiguration {
- public @Nullable String host;
- public Integer port = 5222;
- public String username = "";
- public String password = "";
- public String domain = "";
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.xmppclient.handler;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import org.jivesoftware.smack.*;
-import org.openhab.binding.xmppclient.action.XMPPActions;
-import org.openhab.binding.xmppclient.internal.XMPPClient;
-import org.openhab.core.thing.Bridge;
-import org.openhab.core.thing.Channel;
-import org.openhab.core.thing.ChannelUID;
-import org.openhab.core.thing.ThingStatus;
-import org.openhab.core.thing.ThingStatusDetail;
-import org.openhab.core.thing.binding.BaseBridgeHandler;
-import org.openhab.core.thing.binding.ThingHandlerService;
-import org.openhab.core.types.Command;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link XMPPClientHandler} is responsible for handling commands, which are
- * sent to one of the channels.
- *
- * @author Pavel Gololobov - Initial contribution
- */
-
-public class XMPPClientHandler extends BaseBridgeHandler {
- private final Logger logger = LoggerFactory.getLogger(XMPPClientHandler.class);
- private XMPPClient xmppClient;
- private XMPPClientConfiguration config;
- private final Map<ChannelUID, PublishTriggerChannel> channelStateByChannelUID = new HashMap<>();
-
- public XMPPClientHandler(Bridge thing) {
- super(thing);
- }
-
- public XMPPClient getXMPPClient() {
- return xmppClient;
- }
-
- @Override
- public Collection<Class<? extends ThingHandlerService>> getServices() {
- return Collections.singleton(XMPPActions.class);
- }
-
- @Override
- protected void triggerChannel(ChannelUID channelUID, String event) {
- super.triggerChannel(channelUID, event);
- }
-
- @Override
- public void handleCommand(ChannelUID channelUID, Command command) {
- // not supported
- }
-
- @Override
- public void initialize() {
- updateStatus(ThingStatus.UNKNOWN);
- scheduler.schedule(this::doConnect, 0, TimeUnit.SECONDS);
- }
-
- @Override
- public void dispose() {
- channelStateByChannelUID.values().forEach(c -> c.stop());
- channelStateByChannelUID.clear();
- xmppClient.disconnect();
- super.dispose();
- }
-
- private void doConnect() {
- config = getConfigAs(XMPPClientConfiguration.class);
- xmppClient = new XMPPClient();
- try {
- xmppClient.connect(config.host, config.port, config.username, config.domain, config.password);
- } catch (SmackException | IOException | XMPPException e) {
- logger.info("XMPP connection error", e);
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
- return;
- }
-
- for (Channel channel : thing.getChannels()) {
- final PublishTriggerChannelConfig channelConfig = channel.getConfiguration()
- .as(PublishTriggerChannelConfig.class);
- PublishTriggerChannel c = new PublishTriggerChannel(channelConfig, channel.getUID(), xmppClient, this);
- channelStateByChannelUID.put(channel.getUID(), c);
- logger.info("XMPP added channel {} payload {}", channel.getUID().toString(), channelConfig.payload);
- }
- channelStateByChannelUID.values().forEach(c -> c.start());
-
- updateStatus(ThingStatus.ONLINE);
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.xmppclient.handler;
-
-/**
- * Subscriber interface
- *
- * @author Pavel Gololobov - Initial contribution
- */
-public interface XMPPClientMessageSubscriber {
- public void processMessage(String from, String payload);
-
- public String getName();
-}
import java.util.HashSet;
import java.util.Set;
-import org.jivesoftware.smack.*;
+import org.jivesoftware.smack.AbstractXMPPConnection;
+import org.jivesoftware.smack.ConnectionListener;
+import org.jivesoftware.smack.ReconnectionManager;
+import org.jivesoftware.smack.SmackException;
+import org.jivesoftware.smack.XMPPConnection;
+import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.chat2.Chat;
import org.jivesoftware.smack.chat2.ChatManager;
import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
-import org.openhab.binding.xmppclient.handler.XMPPClientMessageSubscriber;
+import org.openhab.binding.xmppclient.internal.handler.XMPPClientMessageSubscriber;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.xmppclient.internal;
+
+import org.openhab.core.thing.ThingTypeUID;
+
+/**
+ * The {@link XMPPClientBindingConstants} class defines common constants, which are
+ * used across the whole binding.
+ *
+ * @author Pavel Gololobov - Initial contribution
+ */
+public class XMPPClientBindingConstants {
+ private static final String BINDING_ID = "xmppclient";
+
+ // List of all Thing Type UIDs
+ public static final ThingTypeUID BRIDGE_TYPE_XMPP = new ThingTypeUID(BINDING_ID, "xmppBridge");
+ public static final String PUBLISH_TRIGGER_CHANNEL = "publishTrigger";
+}
import java.util.Collections;
import java.util.Set;
-import org.openhab.binding.xmppclient.XMPPClientBindingConstants;
-import org.openhab.binding.xmppclient.handler.XMPPClientHandler;
+import org.openhab.binding.xmppclient.internal.handler.XMPPClientHandler;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.xmppclient.internal.action;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.xmppclient.internal.XMPPClient;
+import org.openhab.binding.xmppclient.internal.handler.XMPPClientHandler;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the automation engine action handler service for the publishXMPP action.
+ *
+ * @author Pavel Gololobov - Initial contribution
+ */
+@ThingActionsScope(name = "xmpp")
+@NonNullByDefault
+public class XMPPActions implements ThingActions {
+ private static final Logger logger = LoggerFactory.getLogger(XMPPActions.class);
+ private @Nullable XMPPClientHandler handler;
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ this.handler = (XMPPClientHandler) handler;
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+
+ @RuleAction(label = "publish a message", description = "Publish a message using XMPP.")
+ public void publishXMPP(@ActionInput(name = "to", label = "To", description = "Send to") @Nullable String to,
+ @ActionInput(name = "text", label = "Text", description = "Message text") @Nullable String text) {
+ XMPPClientHandler clientHandler = handler;
+ if (clientHandler == null) {
+ logger.warn("XMPP ThingHandler is null");
+ return;
+ }
+
+ XMPPClient connection = clientHandler.getXMPPClient();
+ if (connection == null) {
+ logger.warn("XMPP ThingHandler connection is null");
+ return;
+ }
+ if ((to == null) || (text == null)) {
+ logger.info("Skipping XMPP messaging to {} value {}", to, text);
+ return;
+ }
+ connection.sendMessage(to, text);
+ }
+
+ public static void publishXMPP(@Nullable ThingActions actions, @Nullable String to, @Nullable String text) {
+ if (actions instanceof XMPPActions) {
+ ((XMPPActions) actions).publishXMPP(to, text);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of XMPPActions");
+ }
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.xmppclient.internal.handler;
+
+import org.openhab.binding.xmppclient.internal.XMPPClient;
+import org.openhab.core.thing.ChannelUID;
+
+/**
+ * Subscribes to a chat and calls {@link AbstractBrokerHandler#triggerChannel(ChannelUID, String)} if a value has been
+ * received.
+ *
+ * @author Pavel Gololobov - Initial contribution
+ */
+public class PublishTriggerChannel implements XMPPClientMessageSubscriber {
+ private final XMPPClient connection;
+ private final PublishTriggerChannelConfig config;
+ private final ChannelUID uid;
+ private final XMPPClientHandler handler;
+
+ PublishTriggerChannel(PublishTriggerChannelConfig config, ChannelUID uid, XMPPClient connection,
+ XMPPClientHandler handler) {
+ this.config = config;
+ this.uid = uid;
+ this.connection = connection;
+ this.handler = handler;
+ }
+
+ public void start() {
+ connection.subscribe(this);
+ }
+
+ public void stop() {
+ connection.unsubscribe(this);
+ }
+
+ @Override
+ public void processMessage(String from, String payload) {
+ // Check condition if exists
+ String expectedPayload = config.payload;
+ if ((expectedPayload != null) && (!expectedPayload.isEmpty()) && !payload.equals(expectedPayload)) {
+ return;
+ }
+ String eventValue = "";
+ if (!config.separator.isEmpty()) {
+ eventValue = from + config.separator + payload;
+ } else {
+ eventValue = payload;
+ }
+ handler.triggerChannel(uid, eventValue);
+ }
+
+ @Override
+ public String getName() {
+ return uid.toString();
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.xmppclient.internal.handler;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Holds the configuration of a {@link PublishTriggerChannel}.
+ *
+ * @author Pavel Gololobov - Initial contribution
+ */
+@NonNullByDefault
+public class PublishTriggerChannelConfig {
+ public @Nullable String payload;
+ public String separator = "";
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.xmppclient.internal.handler;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * The {@link XMPPClientConfiguration} class contains fields mapping thing configuration parameters.
+ *
+ * @author Pavel Gololobov - Initial contribution
+ */
+@NonNullByDefault
+public class XMPPClientConfiguration {
+ public @Nullable String host;
+ public Integer port = 5222;
+ public String username = "";
+ public String password = "";
+ public String domain = "";
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.xmppclient.internal.handler;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.jivesoftware.smack.*;
+import org.openhab.binding.xmppclient.internal.XMPPClient;
+import org.openhab.binding.xmppclient.internal.action.XMPPActions;
+import org.openhab.core.thing.Bridge;
+import org.openhab.core.thing.Channel;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.binding.BaseBridgeHandler;
+import org.openhab.core.thing.binding.ThingHandlerService;
+import org.openhab.core.types.Command;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link XMPPClientHandler} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Pavel Gololobov - Initial contribution
+ */
+
+public class XMPPClientHandler extends BaseBridgeHandler {
+ private final Logger logger = LoggerFactory.getLogger(XMPPClientHandler.class);
+ private XMPPClient xmppClient;
+ private XMPPClientConfiguration config;
+ private final Map<ChannelUID, PublishTriggerChannel> channelStateByChannelUID = new HashMap<>();
+
+ public XMPPClientHandler(Bridge thing) {
+ super(thing);
+ }
+
+ public XMPPClient getXMPPClient() {
+ return xmppClient;
+ }
+
+ @Override
+ public Collection<Class<? extends ThingHandlerService>> getServices() {
+ return Collections.singleton(XMPPActions.class);
+ }
+
+ @Override
+ protected void triggerChannel(ChannelUID channelUID, String event) {
+ super.triggerChannel(channelUID, event);
+ }
+
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ // not supported
+ }
+
+ @Override
+ public void initialize() {
+ updateStatus(ThingStatus.UNKNOWN);
+ scheduler.schedule(this::doConnect, 0, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public void dispose() {
+ channelStateByChannelUID.values().forEach(c -> c.stop());
+ channelStateByChannelUID.clear();
+ xmppClient.disconnect();
+ super.dispose();
+ }
+
+ private void doConnect() {
+ config = getConfigAs(XMPPClientConfiguration.class);
+ xmppClient = new XMPPClient();
+ try {
+ xmppClient.connect(config.host, config.port, config.username, config.domain, config.password);
+ } catch (SmackException | IOException | XMPPException e) {
+ logger.info("XMPP connection error", e);
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
+ return;
+ }
+
+ for (Channel channel : thing.getChannels()) {
+ final PublishTriggerChannelConfig channelConfig = channel.getConfiguration()
+ .as(PublishTriggerChannelConfig.class);
+ PublishTriggerChannel c = new PublishTriggerChannel(channelConfig, channel.getUID(), xmppClient, this);
+ channelStateByChannelUID.put(channel.getUID(), c);
+ logger.info("XMPP added channel {} payload {}", channel.getUID().toString(), channelConfig.payload);
+ }
+ channelStateByChannelUID.values().forEach(c -> c.start());
+
+ updateStatus(ThingStatus.ONLINE);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.xmppclient.internal.handler;
+
+/**
+ * Subscriber interface
+ *
+ * @author Pavel Gololobov - Initial contribution
+ */
+public interface XMPPClientMessageSubscriber {
+ public void processMessage(String from, String payload);
+
+ public String getName();
+}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.zoneminder.action;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link IZmActions} defines the interface for all thing actions supported by the binding.
- * These methods, parameters, and return types are explained in {@link ZmActions}.
- *
- * @author Mark Hilbush - Initial contribution
- */
-@NonNullByDefault
-public interface IZmActions {
-
- public void triggerAlarm(@Nullable Number alarmDuration);
-
- public void triggerAlarm();
-
- public void cancelAlarm();
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.zoneminder.action;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.zoneminder.internal.handler.ZmMonitorHandler;
-import org.openhab.core.automation.annotation.ActionInput;
-import org.openhab.core.automation.annotation.RuleAction;
-import org.openhab.core.thing.binding.ThingActions;
-import org.openhab.core.thing.binding.ThingActionsScope;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link ZmActions} defines the thing actions provided by this binding.
- *
- * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
- * the test <i>actions instanceof ZmActions</i> fails. This test can fail
- * due to an issue in openHAB core v2.5.0 where the {@link ZmActions} class
- * can be loaded by a different classloader than the <i>actions</i> instance.
- *
- * @author Mark Hilbush - Initial contribution
- */
-@ThingActionsScope(name = "zm")
-@NonNullByDefault
-public class ZmActions implements ThingActions, IZmActions {
- private final Logger logger = LoggerFactory.getLogger(ZmActions.class);
-
- private @Nullable ZmMonitorHandler handler;
-
- @Override
- public @Nullable ThingHandler getThingHandler() {
- return this.handler;
- }
-
- @Override
- public void setThingHandler(@Nullable ThingHandler handler) {
- if (handler instanceof ZmMonitorHandler) {
- this.handler = (ZmMonitorHandler) handler;
- }
- }
-
- private static IZmActions invokeMethodOf(@Nullable ThingActions actions) {
- if (actions == null) {
- throw new IllegalArgumentException("actions cannot be null");
- }
- if (actions.getClass().getName().equals(ZmActions.class.getName())) {
- if (actions instanceof IZmActions) {
- return (IZmActions) actions;
- } else {
- return (IZmActions) Proxy.newProxyInstance(IZmActions.class.getClassLoader(),
- new Class[] { IZmActions.class }, (Object proxy, Method method, Object[] args) -> {
- Method m = actions.getClass().getDeclaredMethod(method.getName(),
- method.getParameterTypes());
- return m.invoke(actions, args);
- });
- }
- }
- throw new IllegalArgumentException("Actions is not an instance of ZmActions");
- }
-
- /**
- * The Trigger Alarm function triggers an alarm that will run for the number of seconds
- * specified by the supplied parameter duration.
- */
- @Override
- @RuleAction(label = "TriggerAlarm", description = "Trigger an alarm on the monitor.")
- public void triggerAlarm(
- @ActionInput(name = "duration", description = "The duration of the alarm in seconds.") @Nullable Number duration) {
- logger.debug("ZmActions: Action 'TriggerAlarm' called");
- ZmMonitorHandler localHandler = handler;
- if (localHandler == null) {
- logger.warn("ZmActions: Action service ThingHandler is null!");
- return;
- }
- localHandler.actionTriggerAlarm(duration);
- }
-
- public static void triggerAlarm(@Nullable ThingActions actions, @Nullable Number alarmDuration) {
- invokeMethodOf(actions).triggerAlarm(alarmDuration);
- }
-
- /**
- * The Trigger Alarm function triggers an alarm that will run for the number of seconds
- * specified in the thing configuration.
- */
- @Override
- @RuleAction(label = "TriggerAlarm", description = "Trigger an alarm on the monitor.")
- public void triggerAlarm() {
- logger.debug("ZmActions: Action 'TriggerAlarm' called");
- ZmMonitorHandler localHandler = handler;
- if (localHandler == null) {
- logger.warn("ZmActions: Action service ThingHandler is null!");
- return;
- }
- localHandler.actionTriggerAlarm();
- }
-
- public static void triggerAlarm(@Nullable ThingActions actions) {
- invokeMethodOf(actions).triggerAlarm();
- }
-
- /**
- * The Cancel Alarm function cancels a running alarm.
- */
- @Override
- @RuleAction(label = "CancelAlarm", description = "Cancel a running alarm.")
- public void cancelAlarm() {
- logger.debug("ZmActions: Action 'CancelAlarm' called");
- ZmMonitorHandler localHandler = handler;
- if (localHandler == null) {
- logger.warn("ZmActions: Action service ThingHandler is null!");
- return;
- }
- localHandler.actionCancelAlarm();
- }
-
- public static void cancelAlarm(@Nullable ThingActions actions) {
- invokeMethodOf(actions).cancelAlarm();
- }
-}
--- /dev/null
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.zoneminder.internal.action;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.zoneminder.internal.handler.ZmMonitorHandler;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link ZmActions} defines the thing actions provided by this binding.
+ *
+ * @author Mark Hilbush - Initial contribution
+ */
+@ThingActionsScope(name = "zm")
+@NonNullByDefault
+public class ZmActions implements ThingActions {
+ private final Logger logger = LoggerFactory.getLogger(ZmActions.class);
+
+ private @Nullable ZmMonitorHandler handler;
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ if (handler instanceof ZmMonitorHandler) {
+ this.handler = (ZmMonitorHandler) handler;
+ }
+ }
+
+ /**
+ * The Trigger Alarm function triggers an alarm that will run for the number of seconds
+ * specified by the supplied parameter duration.
+ */
+ @RuleAction(label = "trigger an alarm", description = "Trigger an alarm on the monitor.")
+ public void triggerAlarm(
+ @ActionInput(name = "duration", description = "The duration of the alarm in seconds.") @Nullable Number duration) {
+ logger.debug("ZmActions: Action 'TriggerAlarm' called");
+ ZmMonitorHandler localHandler = handler;
+ if (localHandler == null) {
+ logger.warn("ZmActions: Action service ThingHandler is null!");
+ return;
+ }
+ localHandler.actionTriggerAlarm(duration);
+ }
+
+ public static void triggerAlarm(@Nullable ThingActions actions, @Nullable Number alarmDuration) {
+ if (actions instanceof ZmActions) {
+ ((ZmActions) actions).triggerAlarm(alarmDuration);
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of ZmActions");
+ }
+ }
+
+ /**
+ * The Trigger Alarm function triggers an alarm that will run for the number of seconds
+ * specified in the thing configuration.
+ */
+ @RuleAction(label = "trigger an alarm", description = "Trigger an alarm on the monitor.")
+ public void triggerAlarm() {
+ logger.debug("ZmActions: Action 'TriggerAlarm' called");
+ ZmMonitorHandler localHandler = handler;
+ if (localHandler == null) {
+ logger.warn("ZmActions: Action service ThingHandler is null!");
+ return;
+ }
+ localHandler.actionTriggerAlarm();
+ }
+
+ public static void triggerAlarm(@Nullable ThingActions actions) {
+ if (actions instanceof ZmActions) {
+ ((ZmActions) actions).triggerAlarm();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of ZmActions");
+ }
+ }
+
+ /**
+ * The Cancel Alarm function cancels a running alarm.
+ */
+ @RuleAction(label = "cancel a running alarm", description = "Cancel a running alarm.")
+ public void cancelAlarm() {
+ logger.debug("ZmActions: Action 'CancelAlarm' called");
+ ZmMonitorHandler localHandler = handler;
+ if (localHandler == null) {
+ logger.warn("ZmActions: Action service ThingHandler is null!");
+ return;
+ }
+ localHandler.actionCancelAlarm();
+ }
+
+ public static void cancelAlarm(@Nullable ThingActions actions) {
+ if (actions instanceof ZmActions) {
+ ((ZmActions) actions).cancelAlarm();
+ } else {
+ throw new IllegalArgumentException("Actions is not an instance of ZmActions");
+ }
+ }
+}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.zoneminder.action.ZmActions;
+import org.openhab.binding.zoneminder.internal.action.ZmActions;
import org.openhab.binding.zoneminder.internal.config.ZmMonitorConfig;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.library.types.DateTimeType;