]> git.basschouten.com Git - openhab-addons.git/commitdiff
[velux] Vane position channel is visible when required (#13271)
authorAndrew Fiddian-Green <software@whitebear.ch>
Sun, 11 Sep 2022 10:44:16 +0000 (11:44 +0100)
committerGitHub <noreply@github.com>
Sun, 11 Sep 2022 10:44:16 +0000 (12:44 +0200)
* [velux] make vanePosition channel dynamic
* [velux] change category of window position from 'blinds' to 'window'

Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
bundles/org.openhab.binding.velux/README.md
bundles/org.openhab.binding.velux/src/main/java/org/openhab/binding/velux/internal/handler/VeluxBridgeHandler.java
bundles/org.openhab.binding.velux/src/main/java/org/openhab/binding/velux/internal/handler/VeluxHandler.java
bundles/org.openhab.binding.velux/src/main/resources/OH-INF/i18n/velux.properties
bundles/org.openhab.binding.velux/src/main/resources/OH-INF/thing/channels.xml
bundles/org.openhab.binding.velux/src/main/resources/OH-INF/thing/rollershutter.xml
bundles/org.openhab.binding.velux/src/main/resources/OH-INF/thing/window.xml

index 0dfc5e258ce1c5e50bf6058a0be8f604da299521..f9b72ae43bb4e08911648bdfbc44de73fef7be7c 100644 (file)
@@ -176,11 +176,12 @@ The supported Channels and their associated channel types are shown below.
 | position     | Rollershutter | Actual position of the window or device.        |
 | limitMinimum | Rollershutter | Minimum limit position of the window or device. |
 | limitMaximum | Rollershutter | Maximum limit position of the window or device. |
-| vanePosition | Dimmer        | Vane position of a Venetian blind.              |
+| vanePosition | Dimmer        | Vane position of a Venetian blind. (optional)   |
 
 The `position`, `limitMinimum`, and `limitMaximum` are the same as described above for "window" Things.
 
 The `vanePosition` Channel only applies to Venetian blinds that have tiltable slats.
+The binding detects whether the device supports a vane position, and if so, it adds the `vanePosition` Channel automatically.
 
 ### Channels for "actuator" Things
 
index e7b02e5a97ffae9d0f6efca13133aad55f5ed4a8..c7bbc209cbaf0e8b0ec3adcfc69be0085092e7d1 100644 (file)
@@ -69,6 +69,7 @@ import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.ThingStatus;
 import org.openhab.core.thing.ThingStatusDetail;
 import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.thing.binding.ThingHandler;
 import org.openhab.core.thing.binding.ThingHandlerService;
 import org.openhab.core.types.Command;
 import org.openhab.core.types.RefreshType;
@@ -465,6 +466,8 @@ public class VeluxBridgeHandler extends ExtendedBaseBridgeHandler implements Vel
             }
         }
 
+        updateDynamicChannels();
+
         veluxBridgeConfiguration.hasChanged = false;
         logger.debug("Velux veluxBridge is online, now.");
         updateStatus(ThingStatus.ONLINE);
@@ -957,4 +960,16 @@ public class VeluxBridgeHandler extends ExtendedBaseBridgeHandler implements Vel
         }
         return ProductBridgeIndex.UNKNOWN;
     }
+
+    /**
+     * Ask all things in the hub to initialise their dynamic vane position channel if they support it.
+     */
+    private void updateDynamicChannels() {
+        getThing().getThings().stream().forEach(thing -> {
+            ThingHandler thingHandler = thing.getHandler();
+            if (thingHandler instanceof VeluxHandler) {
+                ((VeluxHandler) thingHandler).updateDynamicChannels(this);
+            }
+        });
+    }
 }
index e38e358f5502585b6aee9045cbfd2a97da9930d9..15648ce0ca433943e19524c624ba7f9ede55da7e 100644 (file)
@@ -16,11 +16,14 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.velux.internal.config.VeluxThingConfiguration;
+import org.openhab.binding.velux.internal.VeluxBindingConstants;
 import org.openhab.binding.velux.internal.handler.utils.ExtendedBaseThingHandler;
+import org.openhab.binding.velux.internal.handler.utils.Thing2VeluxActuator;
+import org.openhab.binding.velux.internal.things.VeluxProduct;
 import org.openhab.binding.velux.internal.utils.Localization;
 import org.openhab.core.config.core.Configuration;
 import org.openhab.core.thing.Bridge;
+import org.openhab.core.thing.Channel;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingStatus;
@@ -41,8 +44,6 @@ import org.slf4j.LoggerFactory;
 public class VeluxHandler extends ExtendedBaseThingHandler {
     private final Logger logger = LoggerFactory.getLogger(VeluxHandler.class);
 
-    VeluxThingConfiguration configuration = new VeluxThingConfiguration();
-
     public VeluxHandler(Thing thing, Localization localization) {
         super(thing);
         logger.trace("VeluxHandler(thing={},localization={}) constructor called.", thing, localization);
@@ -70,7 +71,6 @@ public class VeluxHandler extends ExtendedBaseThingHandler {
     }
 
     private synchronized void initializeProperties() {
-        configuration = getConfigAs(VeluxThingConfiguration.class);
         logger.trace("initializeProperties() done.");
     }
 
@@ -125,4 +125,37 @@ public class VeluxHandler extends ExtendedBaseThingHandler {
             super.handleConfigurationUpdate(configurationParameters);
         }
     }
+
+    /**
+     * Remove previously statically created vane channel if the device does not support it. Or log a warning if it does
+     * support a vane and the respective channel is missing.
+     *
+     * @param bridgeHandler the calling bridge handler.
+     * @throws IllegalStateException if something went wrong.
+     */
+    public void updateDynamicChannels(VeluxBridgeHandler bridgeHandler) throws IllegalStateException {
+        // roller shutters are the only things with a previously statically created vane channel
+        if (!VeluxBindingConstants.THING_TYPE_VELUX_ROLLERSHUTTER.equals(thing.getThingTypeUID())) {
+            return;
+        }
+
+        String id = VeluxBindingConstants.CHANNEL_VANE_POSITION;
+        ChannelUID uid = new ChannelUID(thing.getUID(), id);
+        Thing2VeluxActuator actuator = new Thing2VeluxActuator(bridgeHandler, uid);
+        VeluxProduct product = bridgeHandler.existingProducts().get(actuator.getProductBridgeIndex());
+
+        if (product.equals(VeluxProduct.UNKNOWN)) {
+            throw new IllegalStateException("updateDynamicChannels(): Product unknown in the bridge");
+        }
+
+        Channel channel = thing.getChannel(id);
+        boolean required = product.supportsVanePosition();
+
+        if (!required && channel != null) {
+            logger.debug("Removing unsupported channel for {}: {}", thing.getUID(), id);
+            updateThing(editThing().withoutChannels(channel).build());
+        } else if (required && channel == null) {
+            logger.warn("Thing {} does not have a '{}' channel => please re-create it", thing.getUID(), id);
+        }
+    }
 }
index 3163c66d154df797a7f450c4ad7995eca3ce5630..67355089c4e225101218713d4df6092a91e2a1bf 100644 (file)
@@ -133,6 +133,8 @@ channel-type.velux.scenes.description = Scenes which are configured on the Bridg
 channel-type.velux.check.label = Check of configuration
 channel-type.velux.check.description = Result of the check of current item configuration.
 #
+channel-type.velux.windowPosition.label = Position
+channel-type.velux.windowPosition.description = Device control (UP, DOWN, STOP, closure 0-100%).
 channel-type.velux.position.label = Position
 channel-type.velux.position.description = Device control (UP, DOWN, STOP, closure 0-100%).
 channel-type.velux.vanePosition.label = Vane Position
index 3a06e242c7387e40c4f63b72c647af750046ec35..a65e3c08d8fd7a3056ecc8179abfec5b10bc0a27 100644 (file)
 
        <!-- Channel Type - Generic Things -->
 
+       <channel-type id="windowPosition">
+               <item-type>Rollershutter</item-type>
+               <label>@text/channel-type.velux.windowPosition.label</label>
+               <description>@text/channel-type.velux.windowPosition.description</description>
+               <category>Window</category>
+               <state min="0" max="100"/>
+       </channel-type>
+
        <channel-type id="position">
                <item-type>Rollershutter</item-type>
                <label>@text/channel-type.velux.position.label</label>
                <description>@text/channel-type.velux.position.description</description>
                <category>Blinds</category>
+               <state min="0" max="100"/>
        </channel-type>
 
        <channel-type id="vanePosition">
                <item-type>Dimmer</item-type>
                <label>@text/channel-type.velux.vanePosition.label</label>
                <description>@text/channel-type.velux.vanePosition.description</description>
-               <category>Blinds</category>
                <state min="0" max="100"/>
        </channel-type>
 
                <item-type>Rollershutter</item-type>
                <label>@text/channel-type.velux.limitMinimum.label</label>
                <description>@text/channel-type.velux.limitMinimum.description</description>
-               <category>Blinds</category>
+               <state min="0" max="100"/>
        </channel-type>
 
        <channel-type id="limitMaximum" advanced="true">
                <item-type>Rollershutter</item-type>
                <label>@text/channel-type.velux.limitMaximum.label</label>
                <description>@text/channel-type.velux.limitMaximum.description</description>
-               <category>Blinds</category>
+               <state min="0" max="100"/>
        </channel-type>
 
        <channel-type id="action">
index f1cd52956b4d9cdfa4237458341ee2bf1d833d09..2918a796656f0584e20c5e751260dd48e70a3ab1 100644 (file)
@@ -17,9 +17,9 @@
                <category>Blinds</category>
                <channels>
                        <channel id="position" typeId="position"/>
+                       <channel id="vanePosition" typeId="vanePosition"/>
                        <channel id="limitMinimum" typeId="limitMinimum"/>
                        <channel id="limitMaximum" typeId="limitMaximum"/>
-                       <channel id="vanePosition" typeId="vanePosition"/>
                </channels>
                <representation-property>serial</representation-property>
                <config-description-ref uri="thing-type:velux:rollershutter"/>
index d4e8f4e2f53afb7dc74cfb55184ddd86d051787d..baa278e0dcc895889d20947ef1be1a87150fad30 100644 (file)
@@ -16,7 +16,7 @@
                <description>@text/thing-type.velux.window.description</description>
                <category>Window</category>
                <channels>
-                       <channel id="position" typeId="position"></channel>
+                       <channel id="position" typeId="windowPosition"></channel>
                        <channel id="limitMinimum" typeId="limitMinimum"/>
                        <channel id="limitMaximum" typeId="limitMaximum"/>
                </channels>