]> git.basschouten.com Git - openhab-addons.git/commitdiff
[somfytahoma] New channel on the gateway to execute scenes (#10346)
authorlolodomo <lg.hc@free.fr>
Sat, 3 Apr 2021 11:35:02 +0000 (13:35 +0200)
committerGitHub <noreply@github.com>
Sat, 3 Apr 2021 11:35:02 +0000 (13:35 +0200)
* [somfytahoma] New channel on the bridge to execute scenes

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
* Review comment: documentation updated

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
* Console command added to list the scenarios IDs

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
* Update state of new channel

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
* Review comment: set auto update policy to recommend

Signed-off-by: Laurent Garnier <lg./hc@free.fr>
bundles/org.openhab.binding.somfytahoma/README.md
bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/SomfyTahomaBindingConstants.java
bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/SomfyTahomaHandlerFactory.java
bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/SomfyTahomaStateDescriptionOptionProvider.java [new file with mode: 0644]
bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/console/SomfyTahomaCommandExtension.java [new file with mode: 0644]
bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/handler/SomfyTahomaGatewayHandler.java
bundles/org.openhab.binding.somfytahoma/src/main/resources/OH-INF/thing/channels.xml
bundles/org.openhab.binding.somfytahoma/src/main/resources/OH-INF/thing/gateway.xml

index fd41cd2a889cd203c67ee2cd97969d468208ba24..1613c6e9e28150f6a94f646a18c2653dbe29fd0b 100644 (file)
@@ -62,6 +62,7 @@ Please see the example below.
 |-------------------------------------------------------------------------------|------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
 | bridge                                                                        | N.A                          | bridge does not expose any channel                                                                                          |
 | gateway                                                                       | status                       | status of your Tahoma gateway                                                                                               |
+| gateway                                                                       | scenarios                    | used to run the scenarios defined in the cloud portal                                                                       |
 | gate                                                                          | gate_command                 | used for controlling your gate (open, close, stop, pedestrian)                                                              |
 | gate                                                                          | gate_state                   | get state of your gate (open, closed, pedestrian)                                                                           |
 | gate                                                                          | gate_position                | get position (0-100%) of your gate (where supported)                                                                        |
@@ -120,6 +121,9 @@ Please see the example below.
 | myfox camera                                                                  | shutter                      | controlling of the camera shutter                                                                                           |
 | myfox alarm                                                                   | myfox_alarm_command          | used for sending commands to Somfy Myfox alarm device                                                                       |
 
+To run a scenario inside a rule for example, the ID of the scenario will be required.
+You can list all the scenarios IDs with the following console command: `somfytahoma <bridgeUID> scenarios`.
+
 ### Remarks
 
 All things which have a RSSI (relative received signal) state, expose a channel "rssi".
index 21f5ec2e08db32275792bbaeadd113296891fb11..87345342c01729a3bfca42d65d2eae55ff3cd08b 100644 (file)
  */
 package org.openhab.binding.somfytahoma.internal;
 
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.core.thing.ThingTypeUID;
@@ -156,6 +160,7 @@ public class SomfyTahomaBindingConstants {
 
     // Gateway
     public static final String STATUS = "status";
+    public static final String SCENARIOS = "scenarios";
 
     // Roller shutter, Awning, Screen, Blind, Garage door, Window, Curtain
     public static final String CONTROL = "control";
index 90d6b99892536ab36a1766cdcb00f7d56115b2fe..bf6c40bbdeee855ee1de569fb74c442877a38796 100644 (file)
@@ -16,7 +16,43 @@ import static org.openhab.binding.somfytahoma.internal.SomfyTahomaBindingConstan
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.somfytahoma.internal.handler.*;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaActionGroupHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaAdjustableSlatsRollerShutterHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaAwningHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaBridgeHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaContactSensorHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaCurtainHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaDimmerLightHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaDockHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaDoorLockHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaElectricitySensorHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaExteriorHeatingSystemHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaExternalAlarmHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaGateHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaGatewayHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaHumiditySensorHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaInternalAlarmHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaLightSensorHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaMyfoxAlarmHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaMyfoxCameraHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaOccupancySensorHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaOnOffHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaOnOffHeatingSystemHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaPergolaHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaPodHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaRollerShutterHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaSilentRollerShutterHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaSirenHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaSmokeSensorHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaTemperatureSensorHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaThermostatHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaUnoRollerShutterHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaValveHeatingSystemHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaVenetianBlindHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaWaterSensorHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaWindowHandleHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaWindowHandler;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaZwaveHeatingSystemHandler;
 import org.openhab.core.io.net.http.HttpClientFactory;
 import org.openhab.core.thing.Bridge;
 import org.openhab.core.thing.Thing;
@@ -43,10 +79,13 @@ public class SomfyTahomaHandlerFactory extends BaseThingHandlerFactory {
     private final Logger logger = LoggerFactory.getLogger(SomfyTahomaHandlerFactory.class);
 
     private final HttpClientFactory httpClientFactory;
+    private final SomfyTahomaStateDescriptionOptionProvider stateDescriptionProvider;
 
     @Activate
-    public SomfyTahomaHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
+    public SomfyTahomaHandlerFactory(@Reference HttpClientFactory httpClientFactory,
+            final @Reference SomfyTahomaStateDescriptionOptionProvider stateDescriptionProvider) {
         this.httpClientFactory = httpClientFactory;
+        this.stateDescriptionProvider = stateDescriptionProvider;
     }
 
     @Override
@@ -64,7 +103,7 @@ public class SomfyTahomaHandlerFactory extends BaseThingHandlerFactory {
         if (thingTypeUID.equals(THING_TYPE_BRIDGE)) {
             return new SomfyTahomaBridgeHandler((Bridge) thing, httpClientFactory);
         } else if (thingTypeUID.equals(THING_TYPE_GATEWAY)) {
-            return new SomfyTahomaGatewayHandler(thing);
+            return new SomfyTahomaGatewayHandler(thing, stateDescriptionProvider);
         } else if (thingTypeUID.equals(THING_TYPE_ROLLERSHUTTER)) {
             return new SomfyTahomaRollerShutterHandler(thing);
         } else if (thingTypeUID.equals(THING_TYPE_ROLLERSHUTTER_SILENT)) {
diff --git a/bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/SomfyTahomaStateDescriptionOptionProvider.java b/bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/SomfyTahomaStateDescriptionOptionProvider.java
new file mode 100644 (file)
index 0000000..653b37a
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2010-2021 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.somfytahoma.internal;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.binding.BaseDynamicStateDescriptionProvider;
+import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
+import org.openhab.core.thing.type.DynamicStateDescriptionProvider;
+import org.openhab.core.types.StateOption;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+/**
+ * Dynamic provider of state options while leaving other state description fields as original.
+ *
+ * @author Laurent Garnier - Initial contribution
+ */
+@Component(service = { DynamicStateDescriptionProvider.class, SomfyTahomaStateDescriptionOptionProvider.class })
+@NonNullByDefault
+public class SomfyTahomaStateDescriptionOptionProvider extends BaseDynamicStateDescriptionProvider {
+
+    public @Nullable List<StateOption> getStateOptions(ChannelUID channelUID) {
+        return channelOptionsMap.get(channelUID);
+    }
+
+    @Reference
+    protected void setChannelTypeI18nLocalizationService(
+            final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
+        this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService;
+    }
+
+    protected void unsetChannelTypeI18nLocalizationService(
+            final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
+        this.channelTypeI18nLocalizationService = null;
+    }
+}
diff --git a/bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/console/SomfyTahomaCommandExtension.java b/bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/console/SomfyTahomaCommandExtension.java
new file mode 100644 (file)
index 0000000..6fd96fe
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2010-2021 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.somfytahoma.internal.console;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaBridgeHandler;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaActionGroup;
+import org.openhab.core.io.console.Console;
+import org.openhab.core.io.console.extensions.AbstractConsoleCommandExtension;
+import org.openhab.core.io.console.extensions.ConsoleCommandExtension;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingRegistry;
+import org.openhab.core.thing.ThingUID;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+/**
+ * The {@link SomfyTahomaCommandExtension} is responsible for handling console commands
+ *
+ * @author Laurent Garnier - Initial contribution
+ */
+
+@NonNullByDefault
+@Component(service = ConsoleCommandExtension.class)
+public class SomfyTahomaCommandExtension extends AbstractConsoleCommandExtension {
+
+    private static final String SCENARIOS = "scenarios";
+
+    private final ThingRegistry thingRegistry;
+
+    @Activate
+    public SomfyTahomaCommandExtension(final @Reference ThingRegistry thingRegistry) {
+        super("somfytahoma", "Interact with the Somfy Tahoma binding.");
+        this.thingRegistry = thingRegistry;
+    }
+
+    @Override
+    public void execute(String[] args, Console console) {
+        if (args.length == 2) {
+            Thing thing = null;
+            try {
+                ThingUID thingUID = new ThingUID(args[0]);
+                thing = thingRegistry.get(thingUID);
+            } catch (IllegalArgumentException e) {
+                thing = null;
+            }
+            ThingHandler thingHandler = null;
+            SomfyTahomaBridgeHandler bridgeHandler = null;
+            if (thing != null) {
+                thingHandler = thing.getHandler();
+                if (thingHandler instanceof SomfyTahomaBridgeHandler) {
+                    bridgeHandler = (SomfyTahomaBridgeHandler) thingHandler;
+                }
+            }
+            if (thing == null) {
+                console.println("Bad thing id '" + args[0] + "'");
+                printUsage(console);
+            } else if (thingHandler == null) {
+                console.println("No handler initialized for the thingUID '" + args[0] + "'");
+                printUsage(console);
+            } else if (bridgeHandler == null) {
+                console.println("'" + args[0] + "' is not a Somfy Tahoma bridgeUID");
+                printUsage(console);
+            } else if (args[1].equals(SCENARIOS)) {
+                for (SomfyTahomaActionGroup actionGroup : bridgeHandler.listActionGroups()) {
+                    console.println("Id is \"" + actionGroup.getOid() + "\" for the scenario \""
+                            + actionGroup.getLabel() + "\"");
+                }
+            } else {
+                printUsage(console);
+            }
+        } else {
+            printUsage(console);
+        }
+    }
+
+    @Override
+    public List<String> getUsages() {
+        return List.of(buildCommandUsage("<bridgeUID> " + SCENARIOS, "list all the scenarios with their id"));
+    }
+}
index 9bab4cebe99032582b08633c3f593ea0caf4e051..42277c8a018704bee905c47b336ac7f08c953eec 100644 (file)
  */
 package org.openhab.binding.somfytahoma.internal.handler;
 
-import static org.openhab.binding.somfytahoma.internal.SomfyTahomaBindingConstants.STATUS;
+import static org.openhab.binding.somfytahoma.internal.SomfyTahomaBindingConstants.*;
 import static org.openhab.core.thing.Thing.PROPERTY_FIRMWARE_VERSION;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.somfytahoma.internal.SomfyTahomaStateDescriptionOptionProvider;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaActionGroup;
 import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaStatus;
 import org.openhab.core.library.types.StringType;
 import org.openhab.core.thing.Channel;
+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.types.Command;
+import org.openhab.core.types.RefreshType;
+import org.openhab.core.types.StateOption;
 
 /**
  * The {@link SomfyTahomaGatewayHandler} is responsible for handling commands,
@@ -33,8 +42,11 @@ import org.openhab.core.thing.ThingStatusDetail;
 @NonNullByDefault
 public class SomfyTahomaGatewayHandler extends SomfyTahomaBaseThingHandler {
 
-    public SomfyTahomaGatewayHandler(Thing thing) {
+    private final SomfyTahomaStateDescriptionOptionProvider stateDescriptionProvider;
+
+    public SomfyTahomaGatewayHandler(Thing thing, SomfyTahomaStateDescriptionOptionProvider stateDescriptionProvider) {
         super(thing);
+        this.stateDescriptionProvider = stateDescriptionProvider;
     }
 
     @Override
@@ -42,6 +54,7 @@ public class SomfyTahomaGatewayHandler extends SomfyTahomaBaseThingHandler {
         if (bridgeStatus != null) {
             if (bridgeStatus == ThingStatus.ONLINE) {
                 refresh(STATUS);
+                refresh(SCENARIOS);
             } else {
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
             }
@@ -52,21 +65,46 @@ public class SomfyTahomaGatewayHandler extends SomfyTahomaBaseThingHandler {
 
     @Override
     public void refresh(String channel) {
-        String id = getGateWayId();
-        SomfyTahomaStatus status = getTahomaStatus(id);
-        String tahomaStatus = status.getStatus();
-        Channel ch = thing.getChannel(channel);
-        if (ch != null) {
-            updateState(ch.getUID(), new StringType(tahomaStatus));
-        }
-        // update the firmware property
-        String fw = status.getProtocolVersion();
-        updateProperty(PROPERTY_FIRMWARE_VERSION, fw);
+        if (channel.equals(STATUS)) {
+            String id = getGateWayId();
+            SomfyTahomaStatus status = getTahomaStatus(id);
+            String tahomaStatus = status.getStatus();
+            Channel ch = thing.getChannel(channel);
+            if (ch != null) {
+                updateState(ch.getUID(), new StringType(tahomaStatus));
+            }
+            // update the firmware property
+            String fw = status.getProtocolVersion();
+            updateProperty(PROPERTY_FIRMWARE_VERSION, fw);
 
-        updateStatus("DISCONNECTED".equals(tahomaStatus) ? ThingStatus.OFFLINE : ThingStatus.ONLINE);
+            updateStatus("DISCONNECTED".equals(tahomaStatus) ? ThingStatus.OFFLINE : ThingStatus.ONLINE);
+        } else if (channel.equals(SCENARIOS)) {
+            SomfyTahomaBridgeHandler handler = getBridgeHandler();
+            if (handler != null) {
+                List<StateOption> options = new ArrayList<>();
+                for (SomfyTahomaActionGroup actionGroup : handler.listActionGroups()) {
+                    options.add(new StateOption(actionGroup.getOid(), actionGroup.getLabel()));
+                }
+                stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), channel), options);
+            }
+        }
     }
 
     public String getGateWayId() {
         return getThing().getConfiguration().get("id").toString();
     }
+
+    @Override
+    public void handleCommand(ChannelUID channelUID, Command command) {
+        super.handleCommand(channelUID, command);
+        if (command instanceof RefreshType) {
+            return;
+        }
+        if (channelUID.getId().equals(SCENARIOS)) {
+            SomfyTahomaBridgeHandler handler = getBridgeHandler();
+            if (handler != null && command instanceof StringType) {
+                handler.executeActionGroup(command.toString());
+            }
+        }
+    }
 }
index 934e625fb99413e42514f87b7fa9aa8a532b7df9..4f20b1c23520a3e3f28c33668af355a75daa234c 100644 (file)
                <description>Operating mode of the Somfy thermostatic valve</description>
                <state readOnly="true"/>
        </channel-type>
+
+       <channel-type id="scenarios">
+               <item-type>String</item-type>
+               <label>Scenarios</label>
+               <description>The scenarios defined in the cloud portal</description>
+               <autoUpdatePolicy>recommend</autoUpdatePolicy>
+       </channel-type>
 </thing:thing-descriptions>
index 8861601a6c6e90fd6987792fff92f7d0c1633bc4..62dffd42b568032f5f65cd56502894afaab5dbad 100644 (file)
@@ -11,6 +11,7 @@
                <label>Somfy Tahoma Gateway</label>
                <channels>
                        <channel id="status" typeId="status"></channel>
+                       <channel id="scenarios" typeId="scenarios"></channel>
                </channels>
                <representation-property>id</representation-property>
                <config-description-ref uri="thing-type:somfytahoma:gateway"/>