]> git.basschouten.com Git - openhab-addons.git/blob
c9b8b79213cc528e8cb15530a20ef8d3ff5d2a48
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.io.homekit.internal;
14
15 import java.util.Arrays;
16 import java.util.List;
17 import java.util.concurrent.ExecutionException;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.openhab.core.io.console.Console;
21 import org.openhab.core.io.console.extensions.AbstractConsoleCommandExtension;
22 import org.openhab.core.io.console.extensions.ConsoleCommandExtension;
23 import org.openhab.io.homekit.Homekit;
24 import org.openhab.io.homekit.internal.accessories.DummyHomekitAccessory;
25 import org.osgi.service.component.annotations.Component;
26 import org.osgi.service.component.annotations.Reference;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import io.github.hapjava.services.Service;
31
32 /**
33  * Console commands for interacting with the HomeKit integration
34  *
35  * @author Andy Lintner - Initial contribution
36  */
37 @Component(service = ConsoleCommandExtension.class)
38 @NonNullByDefault
39 public class HomekitCommandExtension extends AbstractConsoleCommandExtension {
40     private static final String SUBCMD_CLEAR_PAIRINGS = "clearPairings";
41     private static final String SUBCMD_LIST_ACCESSORIES = "list";
42     private static final String SUBCMD_PRINT_ACCESSORY = "show";
43     private static final String SUBCMD_ALLOW_UNAUTHENTICATED = "allowUnauthenticated";
44     private static final String SUBCMD_PRUNE_DUMMY_ACCESSORIES = "pruneDummyAccessories";
45     private static final String SUBCMD_LIST_DUMMY_ACCESSORIES = "listDummyAccessories";
46
47     private final Logger logger = LoggerFactory.getLogger(HomekitCommandExtension.class);
48
49     private @NonNullByDefault({}) Homekit homekit;
50
51     public HomekitCommandExtension() {
52         super("homekit", "Interact with the HomeKit integration.");
53     }
54
55     @Override
56     public void execute(String[] args, Console console) {
57         if (args.length > 0) {
58             String subCommand = args[0];
59             switch (subCommand) {
60                 case SUBCMD_CLEAR_PAIRINGS:
61                     clearHomekitPairings(console);
62                     break;
63
64                 case SUBCMD_ALLOW_UNAUTHENTICATED:
65                     if (args.length > 1) {
66                         boolean allow = Boolean.parseBoolean(args[1]);
67                         allowUnauthenticatedHomekitRequests(allow, console);
68                     } else {
69                         console.println("true/false is required as an argument");
70                     }
71                     break;
72                 case SUBCMD_LIST_ACCESSORIES:
73                     listAccessories(console);
74                     break;
75                 case SUBCMD_PRINT_ACCESSORY:
76                     if (args.length > 1) {
77                         printAccessory(args[1], console);
78                     } else {
79                         console.println("accessory id or name is required as an argument");
80                     }
81                     break;
82                 case SUBCMD_PRUNE_DUMMY_ACCESSORIES:
83                     pruneDummyAccessories(console);
84                     break;
85                 case SUBCMD_LIST_DUMMY_ACCESSORIES:
86                     listDummyAccessories(console);
87                     break;
88                 default:
89                     console.println("Unknown command '" + subCommand + "'");
90                     printUsage(console);
91                     break;
92             }
93         } else {
94             printUsage(console);
95         }
96     }
97
98     @Override
99     public List<String> getUsages() {
100         return Arrays.asList(buildCommandUsage(SUBCMD_LIST_ACCESSORIES, "list all HomeKit accessories"),
101                 buildCommandUsage(SUBCMD_PRINT_ACCESSORY + " <accessory id | accessory name>",
102                         "print additional details of the accessories which partially match provided ID or name."),
103                 buildCommandUsage(SUBCMD_CLEAR_PAIRINGS, "removes all pairings with HomeKit clients."),
104                 buildCommandUsage(SUBCMD_ALLOW_UNAUTHENTICATED + " <boolean>",
105                         "enables or disables unauthenticated access to facilitate debugging"),
106                 buildCommandUsage(SUBCMD_PRUNE_DUMMY_ACCESSORIES,
107                         "removes dummy accessories whose items no longer exist."),
108                 buildCommandUsage(SUBCMD_LIST_DUMMY_ACCESSORIES,
109                         "list dummy accessories whose items no longer exist."));
110     }
111
112     @Reference
113     public void setHomekit(Homekit homekit) {
114         this.homekit = homekit;
115     }
116
117     private void clearHomekitPairings(Console console) {
118         homekit.clearHomekitPairings();
119         console.println("Cleared HomeKit pairings");
120     }
121
122     private void allowUnauthenticatedHomekitRequests(boolean allow, Console console) {
123         homekit.allowUnauthenticatedRequests(allow);
124         console.println((allow ? "Enabled " : "Disabled ") + "unauthenticated HomeKit access");
125     }
126
127     private void pruneDummyAccessories(Console console) {
128         homekit.pruneDummyAccessories();
129         console.println("Dummy accessories pruned.");
130     }
131
132     private void listAccessories(Console console) {
133         homekit.getAccessories().forEach(v -> {
134             try {
135                 console.println(v.getId() + " " + v.getName().get());
136             } catch (InterruptedException | ExecutionException e) {
137                 logger.warn("Cannot list accessories", e);
138             }
139         });
140     }
141
142     private void listDummyAccessories(Console console) {
143         homekit.getAccessories().forEach(v -> {
144             try {
145                 if (v instanceof DummyHomekitAccessory) {
146                     console.println(v.getSerialNumber().get());
147                 }
148             } catch (InterruptedException | ExecutionException e) {
149                 logger.warn("Cannot list accessories", e);
150             }
151         });
152     }
153
154     private void printService(Console console, Service service, int indent) {
155         console.println(" ".repeat(indent) + "Service Type: " + service.getClass().getSimpleName() + " ("
156                 + service.getType() + ")");
157         console.println(" ".repeat(indent + 2) + "Characteristics:");
158         service.getCharacteristics().forEach((c) -> {
159             try {
160                 console.println(
161                         " ".repeat(indent + 4) + c.getClass().getSimpleName() + ": " + c.toJson(0).get().toString());
162             } catch (InterruptedException | ExecutionException e) {
163             }
164         });
165         if (service.getLinkedServices().isEmpty()) {
166             return;
167         }
168         console.println(" ".repeat(indent + 2) + "Linked Services:");
169         service.getLinkedServices().forEach((s) -> printService(console, s, indent + 2));
170     }
171
172     private void printAccessory(String id, Console console) {
173         homekit.getAccessories().forEach(v -> {
174             try {
175                 if (("" + v.getId()).contains(id) || ((v.getName().get() != null)
176                         && (v.getName().get().toUpperCase().contains(id.toUpperCase())))) {
177                     console.println(v.getId() + " " + v.getName().get());
178                     console.println("Services:");
179                     v.getServices().forEach(s -> printService(console, s, 2));
180                     console.println("");
181                 }
182             } catch (InterruptedException | ExecutionException e) {
183                 logger.warn("Cannot print accessory", e);
184             }
185         });
186     }
187 }