]> git.basschouten.com Git - openhab-addons.git/commitdiff
[androiddebugbridge] Added DynamicCommandOptionsProvider to populate 'start-package...
authorChristoph Weitkamp <github@christophweitkamp.de>
Sun, 20 Mar 2022 07:56:58 +0000 (08:56 +0100)
committerGitHub <noreply@github.com>
Sun, 20 Mar 2022 07:56:58 +0000 (08:56 +0100)
Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
bundles/org.openhab.binding.androiddebugbridge/README.md
bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDynamicCommandDescriptionProvider.java [new file with mode: 0644]
bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeHandler.java
bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeHandlerFactory.java

index bc9ed776ac709a02dceb742a8495425e1f1de378..034e07018f154fd256674676b6e2a27c5a9ceb38 100644 (file)
@@ -63,9 +63,9 @@ The available modes are:
 
 The configuration depends on the application, device and version used.
 
-This is a sample of the mediaStateJSONConfig thing configuration:
+This is a sample of the mediaStateJSONConfig thing configuration - the `label` is optional:
 
-`[{"name": "com.amazon.tv.launcher", "mode": "idle"},{"name": "org.jellyfin.androidtv", "mode": "wake_lock", "wakeLockPlayStates": [2,3]},{"name": "com.amazon.firetv.youtube", "mode": "wake_lock", "wakeLockPlayStates": [2]}]`
+`[{"name": "com.amazon.tv.launcher", "mode": "idle"}, {"name": "org.jellyfin.androidtv", "mode": "wake_lock", "wakeLockPlayStates": [2,3]}, {"name": "com.amazon.firetv.youtube", "label":"YouTube", "mode": "wake_lock", "wakeLockPlayStates": [2]}]`
 
 ## Record/Send input events
 
@@ -80,27 +80,26 @@ An example of what you can do:
 
 Please note that events could fail if the input method is removed, for example it could fail if you clone the events of a bluetooth controller and the remote goes offline. This is happening for me when recording the Fire TV remote events but not for my Xiaomi TV which also has a bt remote controller.
 
-
 ## Channels
 
-| channel  | type   | description                  |
-|----------|--------|------------------------------|
-| key-event  | String | Send key event to android device. Possible values listed below |
-| text  | String | Send text to android device |
-| tap  | String | Send tap event to android device (format x,y) |
-| url  | String | Open url in browser |
-| media-volume  | Dimmer | Set or get media volume level on android device |
-| media-control  | Player | Control media on android device |
-| start-package  | String | Run application by package name |
-| stop-package  | String | Stop application by package name |
-| stop-current-package  | String | Stop current application |
-| current-package  | String | Package name of the top application in screen |
-| record-input  | String | Capture events, generate the equivalent command and store it under the provided name |
-| recorded-input  | String | Emulates previously captured input events by name |
-| shutdown  | String | Power off/reboot device (allowed values POWER_OFF, REBOOT) |
-| awake-state  | OnOff | Awake state value. |
-| wake-lock  | Number | Power wake lock value |
-| screen-state  | Switch | Screen power state |
+| channel              | type   | description                                                                                                                   |
+|----------------------|--------|-------------------------------------------------------------------------------------------------------------------------------|
+| key-event            | String | Send key event to android device. Possible values listed below                                                                |
+| text                 | String | Send text to android device                                                                                                   |
+| tap                  | String | Send tap event to android device (format x,y)                                                                                 |
+| url                  | String | Open url in browser                                                                                                           |
+| media-volume         | Dimmer | Set or get media volume level on android device                                                                               |
+| media-control        | Player | Control media on android device                                                                                               |
+| start-package        | String | Run application by package name. The commands for this Channel are populated dynamically based on the `mediaStateJSONConfig`. |
+| stop-package         | String | Stop application by package name                                                                                              |
+| stop-current-package | String | Stop current application                                                                                                      |
+| current-package      | String | Package name of the top application in screen                                                                                 |
+| record-input         | String | Capture events, generate the equivalent command and store it under the provided name                                          |
+| recorded-input       | String | Emulates previously captured input events by name                                                                             |
+| shutdown             | String | Power off/reboot device (allowed values POWER_OFF, REBOOT)                                                                    |
+| awake-state          | OnOff  | Awake state value.                                                                                                            |
+| wake-lock            | Number | Power wake lock value                                                                                                         |
+| screen-state         | Switch | Screen power state                                                                                                            |
 
 #### Available key-event values:
 
diff --git a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDynamicCommandDescriptionProvider.java b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDynamicCommandDescriptionProvider.java
new file mode 100644 (file)
index 0000000..75311dc
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2010-2022 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.androiddebugbridge.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.events.EventPublisher;
+import org.openhab.core.thing.binding.BaseDynamicCommandDescriptionProvider;
+import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
+import org.openhab.core.thing.link.ItemChannelLinkRegistry;
+import org.openhab.core.thing.type.DynamicCommandDescriptionProvider;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+/**
+ * Dynamic provider of command options.
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+@Component(service = { DynamicCommandDescriptionProvider.class,
+        AndroidDebugBridgeDynamicCommandDescriptionProvider.class })
+@NonNullByDefault
+public class AndroidDebugBridgeDynamicCommandDescriptionProvider extends BaseDynamicCommandDescriptionProvider {
+    @Activate
+    public AndroidDebugBridgeDynamicCommandDescriptionProvider(final @Reference EventPublisher eventPublisher, //
+            final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry, //
+            final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
+        this.eventPublisher = eventPublisher;
+        this.itemChannelLinkRegistry = itemChannelLinkRegistry;
+        this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService;
+    }
+}
index 2728f98c716db3c371f03c84e552a2c52712a2fa..c442ebfca5246fc9c22cb3f70dc5ef7c633f9ea8 100644 (file)
@@ -22,6 +22,7 @@ import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -38,6 +39,7 @@ import org.openhab.core.thing.ThingStatus;
 import org.openhab.core.thing.ThingStatusDetail;
 import org.openhab.core.thing.binding.BaseThingHandler;
 import org.openhab.core.types.Command;
+import org.openhab.core.types.CommandOption;
 import org.openhab.core.types.RefreshType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -65,6 +67,8 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
     private static final Gson GSON = new Gson();
     private static final Pattern RECORD_NAME_PATTERN = Pattern.compile("^[A-Za-z0-9_]*$");
     private final Logger logger = LoggerFactory.getLogger(AndroidDebugBridgeHandler.class);
+
+    private final AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider;
     private final AndroidDebugBridgeDevice adbConnection;
     private int maxMediaVolume = 0;
     private AndroidDebugBridgeConfiguration config = new AndroidDebugBridgeConfiguration();
@@ -72,8 +76,10 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
     private AndroidDebugBridgeMediaStatePackageConfig @Nullable [] packageConfigs = null;
     private boolean deviceAwake = false;
 
-    public AndroidDebugBridgeHandler(Thing thing) {
+    public AndroidDebugBridgeHandler(Thing thing,
+            AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider) {
         super(thing);
+        this.commandDescriptionProvider = commandDescriptionProvider;
         this.adbConnection = new AndroidDebugBridgeDevice(scheduler);
     }
 
@@ -317,12 +323,18 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
     }
 
     private void loadMediaStateConfig(String mediaStateJSONConfig) {
+        List<CommandOption> commandOptions;
         try {
-            this.packageConfigs = GSON.fromJson(mediaStateJSONConfig,
-                    AndroidDebugBridgeMediaStatePackageConfig[].class);
+            packageConfigs = GSON.fromJson(mediaStateJSONConfig, AndroidDebugBridgeMediaStatePackageConfig[].class);
+            commandOptions = Arrays.stream(packageConfigs)
+                    .map(AndroidDebugBridgeMediaStatePackageConfig::toCommandOption)
+                    .collect(Collectors.toUnmodifiableList());
         } catch (JsonSyntaxException e) {
             logger.warn("unable to parse media state config: {}", e.getMessage());
+            commandOptions = List.of();
         }
+        commandDescriptionProvider.setCommandOptions(new ChannelUID(getThing().getUID(), START_PACKAGE_CHANNEL),
+                commandOptions);
     }
 
     @Override
@@ -449,7 +461,12 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
 
     static class AndroidDebugBridgeMediaStatePackageConfig {
         public String name = "";
+        public @Nullable String label;
         public String mode = "";
         public List<Integer> wakeLockPlayStates = List.of();
+
+        public CommandOption toCommandOption() {
+            return new CommandOption(name, label == null ? name : label);
+        }
     }
 }
index f2bd1710aa0b5f5ac83dc9695ad306133a888910..404fd4b9a2e1d7c38147a3b6133d4883b2e2d5c1 100644 (file)
@@ -21,7 +21,9 @@ import org.openhab.core.thing.ThingTypeUID;
 import org.openhab.core.thing.binding.BaseThingHandlerFactory;
 import org.openhab.core.thing.binding.ThingHandler;
 import org.openhab.core.thing.binding.ThingHandlerFactory;
+import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
 
 /**
  * The {@link AndroidDebugBridgeHandlerFactory} is responsible for creating things and thing
@@ -33,6 +35,14 @@ import org.osgi.service.component.annotations.Component;
 @Component(configurationPid = BINDING_CONFIGURATION_PID, service = ThingHandlerFactory.class)
 public class AndroidDebugBridgeHandlerFactory extends BaseThingHandlerFactory {
 
+    private final AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider;
+
+    @Activate
+    public AndroidDebugBridgeHandlerFactory(
+            final @Reference AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider) {
+        this.commandDescriptionProvider = commandDescriptionProvider;
+    }
+
     @Override
     public boolean supportsThingType(ThingTypeUID thingTypeUID) {
         return SUPPORTED_THING_TYPES.contains(thingTypeUID);
@@ -42,7 +52,7 @@ public class AndroidDebugBridgeHandlerFactory extends BaseThingHandlerFactory {
     protected @Nullable ThingHandler createHandler(Thing thing) {
         ThingTypeUID thingTypeUID = thing.getThingTypeUID();
         if (THING_TYPE_ANDROID_DEVICE.equals(thingTypeUID)) {
-            return new AndroidDebugBridgeHandler(thing);
+            return new AndroidDebugBridgeHandler(thing, commandDescriptionProvider);
         }
         return null;
     }