Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[androidtv] Adds CLI Interface #15146

Merged
merged 6 commits into from
Jul 15, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions bundles/org.openhab.binding.androidtv/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <thingUID> <channel> <command>
```

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.
morph166955 marked this conversation as resolved.
Show resolved Hide resolved

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
morph166955 marked this conversation as resolved.
Show resolved Hide resolved
```

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
morph166955 marked this conversation as resolved.
Show resolved Hide resolved
```

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.
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could consider implementing ConsoleCommandCompleter for tab completion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely agreed and it's on my list. I wanted to get the i18n bits sorted first to reduce duplicate work. That PR is pending.


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 id '" + args[0] + "'");
morph166955 marked this conversation as resolved.
Show resolved Hide resolved
printUsage(console);
} else if (thingHandler == null) {
console.println("No handler initialized for the thing id '" + args[0] + "'");
morph166955 marked this conversation as resolved.
Show resolved Hide resolved
printUsage(console);
} else if (handler == null) {
console.println("'" + args[0] + "' is not a AndroidTV thing id");
morph166955 marked this conversation as resolved.
Show resolved Hide resolved
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<String> getUsages() {
return List.of(buildCommandUsage("<thingUID> <channelname> <command>", "Send a command to a specific channel"));
}
}