2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.velux.internal.action;
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.openhab.binding.velux.internal.handler.VeluxBridgeHandler;
18 import org.openhab.binding.velux.internal.things.VeluxProduct.ProductBridgeIndex;
19 import org.openhab.core.automation.annotation.ActionInput;
20 import org.openhab.core.automation.annotation.ActionOutput;
21 import org.openhab.core.automation.annotation.RuleAction;
22 import org.openhab.core.library.types.PercentType;
23 import org.openhab.core.thing.binding.ThingActions;
24 import org.openhab.core.thing.binding.ThingActionsScope;
25 import org.openhab.core.thing.binding.ThingHandler;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * The {@link VeluxActions} implementation of the rule action for rebooting the bridge
32 * @author Andrew Fiddian-Green - Initial contribution
34 @ThingActionsScope(name = "velux")
36 public class VeluxActions implements ThingActions {
38 private final Logger logger = LoggerFactory.getLogger(VeluxActions.class);
40 private @Nullable VeluxBridgeHandler bridgeHandler;
43 public void setThingHandler(@Nullable ThingHandler handler) {
44 if (handler instanceof VeluxBridgeHandler veluxBridgeHandler) {
45 this.bridgeHandler = veluxBridgeHandler;
50 public @Nullable ThingHandler getThingHandler() {
51 return this.bridgeHandler;
54 @RuleAction(label = "@text/action.reboot.label", description = "@text/action.reboot.descr")
55 public @ActionOutput(name = "running", type = "java.lang.Boolean", label = "@text/action.run.label", description = "@text/action.run.descr") Boolean rebootBridge()
56 throws IllegalStateException {
57 logger.trace("rebootBridge(): action called");
58 VeluxBridgeHandler bridgeHandler = this.bridgeHandler;
59 if (bridgeHandler == null) {
60 throw new IllegalStateException("Bridge instance is null");
62 return bridgeHandler.rebootBridge();
65 @RuleAction(label = "@text/action.moveRelative.label", description = "@text/action.moveRelative.descr")
66 public @ActionOutput(name = "running", type = "java.lang.Boolean", label = "@text/action.run.label", description = "@text/action.run.descr") Boolean moveRelative(
67 @ActionInput(name = "nodeId", label = "@text/action.node.label", description = "@text/action.node.descr") @Nullable String nodeId,
68 @ActionInput(name = "relativePercent", label = "@text/action.relative.label", description = "@text/action.relative.descr") @Nullable String relativePercent)
69 throws NumberFormatException, IllegalStateException, IllegalArgumentException {
70 logger.trace("moveRelative(): action called");
71 VeluxBridgeHandler bridgeHandler = this.bridgeHandler;
72 if (bridgeHandler == null) {
73 throw new IllegalStateException("Bridge instance is null");
76 throw new IllegalArgumentException("Node Id is null");
78 int node = Integer.parseInt(nodeId);
79 if (node < 0 || node > 200) {
80 throw new NumberFormatException("Node Id out of range");
82 if (relativePercent == null) {
83 throw new IllegalArgumentException("Relative Percent is null");
85 int relPct = Integer.parseInt(relativePercent);
86 if (Math.abs(relPct) > 100) {
87 throw new NumberFormatException("Relative Percent out of range");
89 return bridgeHandler.moveRelative(node, relPct);
93 * Static method to send a reboot command to a Velux Bridge
95 * @param actions ThingActions from the caller
96 * @return true if the command was sent
97 * @throws IllegalArgumentException if actions is invalid
98 * @throws IllegalStateException if anything else is wrong
100 public static Boolean rebootBridge(@Nullable ThingActions actions)
101 throws IllegalArgumentException, IllegalStateException {
102 if (!(actions instanceof VeluxActions)) {
103 throw new IllegalArgumentException("Unsupported action");
105 return ((VeluxActions) actions).rebootBridge();
109 * Static method to send a relative move command to a Velux actuator
111 * @param actions ThingActions from the caller
112 * @param nodeId the node Id in the bridge
113 * @param relativePercent the target position relative to its current position (-100% <= relativePercent <= +100%)
114 * @return true if the command was sent
115 * @throws IllegalArgumentException if actions is invalid
116 * @throws IllegalStateException if anything else is wrong
117 * @throws NumberFormatException if either of nodeId or relativePercent is not an integer, or out of range
119 public static Boolean moveRelative(@Nullable ThingActions actions, @Nullable String nodeId,
120 @Nullable String relativePercent)
121 throws IllegalArgumentException, NumberFormatException, IllegalStateException {
122 if (!(actions instanceof VeluxActions)) {
123 throw new IllegalArgumentException("Unsupported action");
125 return ((VeluxActions) actions).moveRelative(nodeId, relativePercent);
128 @RuleAction(label = "@text/action.moveMainAndVane.label", description = "@text/action.moveMainAndVane.descr")
129 public @ActionOutput(name = "running", type = "java.lang.Boolean", label = "@text/action.run.label", description = "@text/action.run.descr") Boolean moveMainAndVane(
130 @ActionInput(name = "thingName", label = "@text/action.thing.label", description = "@text/action.thing.descr") @Nullable String thingName,
131 @ActionInput(name = "mainPercent", label = "@text/action.main.label", description = "@text/action.main.descr") @Nullable Integer mainPercent,
132 @ActionInput(name = "vanePercent", label = "@text/action.vane.label", description = "@text/action.vane.descr") @Nullable Integer vanePercent)
133 throws NumberFormatException, IllegalArgumentException, IllegalStateException {
134 logger.trace("moveMainAndVane(thingName:'{}', mainPercent:{}, vanePercent:{}) action called", thingName,
135 mainPercent, vanePercent);
136 VeluxBridgeHandler bridgeHandler = this.bridgeHandler;
137 if (bridgeHandler == null) {
138 throw new IllegalStateException("Bridge instance is null");
140 if (thingName == null) {
141 throw new IllegalArgumentException("Thing name is null");
143 ProductBridgeIndex node = bridgeHandler.getProductBridgeIndex(thingName);
144 if (ProductBridgeIndex.UNKNOWN.equals(node)) {
145 throw new IllegalArgumentException("Bridge does not contain a thing with name " + thingName);
147 if (mainPercent == null) {
148 throw new IllegalArgumentException("Main perent is null");
150 PercentType mainPercentType = new PercentType(mainPercent);
151 if (vanePercent == null) {
152 throw new IllegalArgumentException("Vane perent is null");
154 PercentType vanePercenType = new PercentType(vanePercent);
155 return bridgeHandler.moveMainAndVane(node, mainPercentType, vanePercenType);
159 * Action to simultaneously move the shade main position and vane positions.
162 * @param actions ThingActions from the caller
163 * @param thingName the name of the thing to be moved (e.g. 'velux:rollershutter:hubid:thingid')
164 * @param mainPercent the desired main position (range 0..100)
165 * @param vanePercent the desired vane position (range 0..100)
166 * @return true if the command was sent
167 * @throws NumberFormatException if any of the arguments are not an integer
168 * @throws IllegalArgumentException if any of the arguments are invalid
169 * @throws IllegalStateException if anything else is wrong
171 public static Boolean moveMainAndVane(@Nullable ThingActions actions, @Nullable String thingName,
172 @Nullable Integer mainPercent, @Nullable Integer vanePercent)
173 throws NumberFormatException, IllegalArgumentException, IllegalStateException {
174 if (!(actions instanceof VeluxActions)) {
175 throw new IllegalArgumentException("Unsupported action");
177 return ((VeluxActions) actions).moveMainAndVane(thingName, mainPercent, vanePercent);