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
114 * ({@code -100% <= relativePercent <= +100%})
115 * @return true if the command was sent
116 * @throws IllegalArgumentException if actions is invalid
117 * @throws IllegalStateException if anything else is wrong
118 * @throws NumberFormatException if either of nodeId or relativePercent is not an integer, or out of range
120 public static Boolean moveRelative(@Nullable ThingActions actions, @Nullable String nodeId,
121 @Nullable String relativePercent)
122 throws IllegalArgumentException, NumberFormatException, IllegalStateException {
123 if (!(actions instanceof VeluxActions)) {
124 throw new IllegalArgumentException("Unsupported action");
126 return ((VeluxActions) actions).moveRelative(nodeId, relativePercent);
129 @RuleAction(label = "@text/action.moveMainAndVane.label", description = "@text/action.moveMainAndVane.descr")
130 public @ActionOutput(name = "running", type = "java.lang.Boolean", label = "@text/action.run.label", description = "@text/action.run.descr") Boolean moveMainAndVane(
131 @ActionInput(name = "thingName", label = "@text/action.thing.label", description = "@text/action.thing.descr") @Nullable String thingName,
132 @ActionInput(name = "mainPercent", label = "@text/action.main.label", description = "@text/action.main.descr") @Nullable Integer mainPercent,
133 @ActionInput(name = "vanePercent", label = "@text/action.vane.label", description = "@text/action.vane.descr") @Nullable Integer vanePercent)
134 throws NumberFormatException, IllegalArgumentException, IllegalStateException {
135 logger.trace("moveMainAndVane(thingName:'{}', mainPercent:{}, vanePercent:{}) action called", thingName,
136 mainPercent, vanePercent);
137 VeluxBridgeHandler bridgeHandler = this.bridgeHandler;
138 if (bridgeHandler == null) {
139 throw new IllegalStateException("Bridge instance is null");
141 if (thingName == null) {
142 throw new IllegalArgumentException("Thing name is null");
144 ProductBridgeIndex node = bridgeHandler.getProductBridgeIndex(thingName);
145 if (ProductBridgeIndex.UNKNOWN.equals(node)) {
146 throw new IllegalArgumentException("Bridge does not contain a thing with name " + thingName);
148 if (mainPercent == null) {
149 throw new IllegalArgumentException("Main perent is null");
151 PercentType mainPercentType = new PercentType(mainPercent);
152 if (vanePercent == null) {
153 throw new IllegalArgumentException("Vane perent is null");
155 PercentType vanePercenType = new PercentType(vanePercent);
156 return bridgeHandler.moveMainAndVane(node, mainPercentType, vanePercenType);
160 * Action to simultaneously move the shade main position and vane positions.
163 * @param actions ThingActions from the caller
164 * @param thingName the name of the thing to be moved (e.g. 'velux:rollershutter:hubid:thingid')
165 * @param mainPercent the desired main position (range 0..100)
166 * @param vanePercent the desired vane position (range 0..100)
167 * @return true if the command was sent
168 * @throws NumberFormatException if any of the arguments are not an integer
169 * @throws IllegalArgumentException if any of the arguments are invalid
170 * @throws IllegalStateException if anything else is wrong
172 public static Boolean moveMainAndVane(@Nullable ThingActions actions, @Nullable String thingName,
173 @Nullable Integer mainPercent, @Nullable Integer vanePercent)
174 throws NumberFormatException, IllegalArgumentException, IllegalStateException {
175 if (!(actions instanceof VeluxActions)) {
176 throw new IllegalArgumentException("Unsupported action");
178 return ((VeluxActions) actions).moveMainAndVane(thingName, mainPercent, vanePercent);