diff --git a/bundles/org.openhab.binding.androidtv/README.md b/bundles/org.openhab.binding.androidtv/README.md index b3132569f..f53cc9dfa 100644 --- a/bundles/org.openhab.binding.androidtv/README.md +++ b/bundles/org.openhab.binding.androidtv/README.md @@ -123,16 +123,46 @@ You may also send it a command of the app package name (e.g. com.google.android. KEYCODE values are listed at the bottom of this README. NOTE: Not all KEYCODES work on all devices. Keycodes above 255 have not been tested. +## Command Line Access + +All String type channels may receive commands from inside the karaf cli, even if there are no items configured. + +This can be particularly useful for the Pin Code Process as well as for testing. + +Syntax: + +```shell +openhab> openhab:androidtv +``` + +Example usage: + +```shell +openhab> openhab:androidtv androidtv:googletv:theater keypress KEY_POWER +``` + ## Pin Code Process For the AndroidTV to be successfully accessed an on-screen PIN authentication is required on the first connection. To begin the PIN process, send the text "REQUEST" to the pincode channel while watching your AndroidTV. +CLI Example Usage: + +```shell +openhab> openhab:androidtv androidtv:googletv:theater pincode REQUEST +``` + A 6 digit PIN should be displayed on the screen. To complete the PIN process, send the PIN displayed to the pincode channel. +CLI Example Usage: + +```shell +openhab> openhab:androidtv androidtv:googletv:theater pincode abc123 +``` + The display should return back to where it was originally. If you are on a ShieldTV you must run that process a second time to authenticate the GoogleTV protocol stack. diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/console/AndroidTVCommandExtension.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/console/AndroidTVCommandExtension.java new file mode 100644 index 000000000..f34c8158b --- /dev/null +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/console/AndroidTVCommandExtension.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2010-2023 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.androidtv.internal.console; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.androidtv.internal.AndroidTVHandler; +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.library.types.StringType; +import org.openhab.core.thing.ChannelUID; +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.openhab.core.types.Command; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link AndroidTVCommandExtension} is responsible for handling console commands + * + * @author Ben Rosenblum - Initial contribution + */ + +@NonNullByDefault +@Component(service = ConsoleCommandExtension.class) +public class AndroidTVCommandExtension extends AbstractConsoleCommandExtension { + + private final Logger logger = LoggerFactory.getLogger(AndroidTVCommandExtension.class); + private final ThingRegistry thingRegistry; + + @Activate + public AndroidTVCommandExtension(final @Reference ThingRegistry thingRegistry) { + super("androidtv", "Interact with the AndroidTV binding channels directly."); + this.thingRegistry = thingRegistry; + } + + @Override + public void execute(String[] args, Console console) { + if (args.length == 3) { + logger.trace("Received CLI Command: {} {} |||{}|||", args[0], args[1], args[2]); + Thing thing = null; + try { + ThingUID thingUID = new ThingUID(args[0]); + thing = thingRegistry.get(thingUID); + } catch (IllegalArgumentException e) { + thing = null; + } + ThingHandler thingHandler = null; + AndroidTVHandler handler = null; + if (thing != null) { + thingHandler = thing.getHandler(); + if (thingHandler instanceof AndroidTVHandler) { + handler = (AndroidTVHandler) thingHandler; + } + } + if (thing == null) { + console.println("Bad thing uid '" + args[0] + "'"); + printUsage(console); + } else if (thingHandler == null) { + console.println("No handler initialized for the thing uid '" + args[0] + "'"); + printUsage(console); + } else if (handler == null) { + console.println("'" + args[0] + "' is not an AndroidTV thing uid"); + printUsage(console); + } else { + String channel = args[0] + ":" + args[1]; + ChannelUID channelUID = new ChannelUID(channel); + Command command = (Command) new StringType(args[2]); + logger.debug("Sending CLI Command to Handler: {} |||{}|||", channelUID.toString(), command.toString()); + handler.handleCommand(channelUID, command); + } + } else { + printUsage(console); + } + } + + @Override + public List getUsages() { + return List.of(buildCommandUsage(" ", "Send a command to a specific channel")); + } +}