2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.vizio.internal.console;
15 import static org.openhab.binding.vizio.internal.VizioBindingConstants.*;
17 import java.math.BigDecimal;
18 import java.util.List;
19 import java.util.Random;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jetty.client.HttpClient;
23 import org.openhab.binding.vizio.internal.VizioException;
24 import org.openhab.binding.vizio.internal.communication.VizioCommunicator;
25 import org.openhab.binding.vizio.internal.dto.pairing.PairingComplete;
26 import org.openhab.binding.vizio.internal.handler.VizioHandler;
27 import org.openhab.core.io.console.Console;
28 import org.openhab.core.io.console.extensions.AbstractConsoleCommandExtension;
29 import org.openhab.core.io.console.extensions.ConsoleCommandExtension;
30 import org.openhab.core.io.net.http.HttpClientFactory;
31 import org.openhab.core.thing.Thing;
32 import org.openhab.core.thing.ThingRegistry;
33 import org.openhab.core.thing.ThingUID;
34 import org.openhab.core.thing.binding.ThingHandler;
35 import org.osgi.service.component.annotations.Activate;
36 import org.osgi.service.component.annotations.Component;
37 import org.osgi.service.component.annotations.Reference;
40 * The {@link VizioCommandExtension} is responsible for handling console commands
42 * @author Michael Lobstein - Initial contribution
46 @Component(service = ConsoleCommandExtension.class)
47 public class VizioCommandExtension extends AbstractConsoleCommandExtension {
48 private static final String START_PAIRING = "start_pairing";
49 private static final String SUBMIT_CODE = "submit_code";
51 private final ThingRegistry thingRegistry;
52 private final HttpClient httpClient;
55 public VizioCommandExtension(final @Reference ThingRegistry thingRegistry,
56 final @Reference HttpClientFactory httpClientFactory) {
57 super("vizio", "Interact with the Vizio binding to get an authentication token from the TV.");
58 this.thingRegistry = thingRegistry;
59 this.httpClient = httpClientFactory.getCommonHttpClient();
63 public void execute(String[] args, Console console) {
64 if (args.length == 3) {
67 ThingUID thingUID = new ThingUID(args[0]);
68 thing = thingRegistry.get(thingUID);
69 } catch (IllegalArgumentException e) {
72 ThingHandler thingHandler = null;
73 VizioHandler handler = null;
75 thingHandler = thing.getHandler();
76 if (thingHandler instanceof VizioHandler) {
77 handler = (VizioHandler) thingHandler;
81 console.println("Bad thing id '" + args[0] + "'");
83 } else if (thingHandler == null) {
84 console.println("No handler initialized for the thing id '" + args[0] + "'");
86 } else if (handler == null) {
87 console.println("'" + args[0] + "' is not a Vizio thing id");
90 String host = (String) thing.getConfiguration().get(PROPERTY_HOST_NAME);
91 BigDecimal port = (BigDecimal) thing.getConfiguration().get(PROPERTY_PORT);
93 if (host == null || host.isEmpty() || port.signum() < 1) {
95 "Error! Host Name and Port must be specified in thing configuration before paring.");
97 } else if (host.contains(":")) {
99 host = "[" + host + "]";
102 VizioCommunicator communicator = new VizioCommunicator(httpClient, host, port.intValue(), EMPTY);
107 Random rng = new Random();
109 int pairingDeviceId = rng.nextInt(100000);
110 int pairingToken = communicator.startPairing(args[2], pairingDeviceId).getItem()
111 .getPairingReqToken();
112 if (pairingToken != -1) {
113 handler.setPairingDeviceId(pairingDeviceId);
114 handler.setPairingToken(pairingToken);
116 console.println("Pairing has been started!");
118 "Please note the 4 digit code displayed on the TV and substitute it into the following console command:");
120 "openhab:vizio " + handler.getThing().getUID() + " " + SUBMIT_CODE + " <NNNN>");
122 console.println("Unable to obtain pairing token!");
124 } catch (VizioException e) {
125 console.println("Error! Unable to start pairing process.");
126 console.println("Exception was: " + e.getMessage());
131 int pairingDeviceId = handler.getPairingDeviceId();
132 int pairingToken = handler.getPairingToken();
134 if (pairingDeviceId < 0 || pairingToken < 0) {
135 console.println("Error! '" + START_PAIRING + "' command must be completed first.");
137 "Please issue the following command and substitute the desired device name.");
138 console.println("openhab:vizio " + handler.getThing().getUID() + " " + START_PAIRING
143 Integer.valueOf(args[2]);
144 PairingComplete authTokenResp = communicator.submitPairingCode(pairingDeviceId, args[2],
146 if (authTokenResp.getItem().getAuthToken() != EMPTY) {
147 console.println("Pairing complete!");
148 console.println("The auth token: " + authTokenResp.getItem().getAuthToken()
149 + " was received and will be added to the thing configuration.");
151 "If the thing is provisioned via a file, the token must be manually added to the thing configuration.");
153 handler.setPairingDeviceId(-1);
154 handler.setPairingToken(-1);
155 handler.saveAuthToken(authTokenResp.getItem().getAuthToken());
157 console.println("Unable to obtain auth token!");
159 } catch (NumberFormatException nfe) {
161 "Error! Pairing code must be numeric. Check console command and try again.");
162 } catch (VizioException e) {
163 console.println("Error! Unable to complete pairing process.");
164 console.println("Exception was: " + e.getMessage());
178 public List<String> getUsages() {
179 return List.of(new String[] {
180 buildCommandUsage("<thingUID> " + START_PAIRING + " <deviceName>", "start pairing process"),
181 buildCommandUsage("<thingUID> " + SUBMIT_CODE + " <pairingCode>", "submit pairing code") });