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.jellyfin.internal.discovery;
15 import static org.openhab.binding.jellyfin.internal.JellyfinBindingConstants.DISCOVERY_RESULT_TTL_SEC;
16 import static org.openhab.binding.jellyfin.internal.JellyfinBindingConstants.THING_TYPE_CLIENT;
17 import static org.openhab.binding.jellyfin.internal.JellyfinBindingConstants.THING_TYPE_SERVER;
19 import java.util.HashMap;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.jellyfin.sdk.api.client.exception.ApiClientException;
26 import org.jellyfin.sdk.api.client.exception.InvalidStatusException;
27 import org.jellyfin.sdk.model.api.SessionInfo;
28 import org.openhab.binding.jellyfin.internal.handler.JellyfinServerHandler;
29 import org.openhab.binding.jellyfin.internal.util.SyncCallback;
30 import org.openhab.core.config.discovery.AbstractDiscoveryService;
31 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
32 import org.openhab.core.thing.Thing;
33 import org.openhab.core.thing.ThingStatus;
34 import org.openhab.core.thing.ThingUID;
35 import org.openhab.core.thing.binding.ThingHandler;
36 import org.openhab.core.thing.binding.ThingHandlerService;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
41 * The {@link JellyfinClientDiscoveryService} discover Jellyfin clients connected to the server.
43 * @author Miguel Alvarez - Initial contribution
46 public class JellyfinClientDiscoveryService extends AbstractDiscoveryService implements ThingHandlerService {
47 private final Logger logger = LoggerFactory.getLogger(JellyfinClientDiscoveryService.class);
48 private @Nullable JellyfinServerHandler bridgeHandler;
50 public JellyfinClientDiscoveryService() throws IllegalArgumentException {
51 super(Set.of(THING_TYPE_SERVER), 60);
55 protected void startScan() {
56 var bridgeHandler = this.bridgeHandler;
57 if (bridgeHandler == null) {
58 logger.warn("missing bridge aborting");
61 if (!bridgeHandler.getThing().getStatus().equals(ThingStatus.ONLINE)) {
62 logger.warn("Server handler {} is not online.", bridgeHandler.getThing().getLabel());
65 logger.debug("Searching devices for server {}", bridgeHandler.getThing().getLabel());
67 bridgeHandler.getControllableSessions().forEach(this::discoverDevice);
68 } catch (SyncCallback.SyncCallbackError syncCallbackError) {
69 logger.error("Unexpected error: {}", syncCallbackError.getMessage());
70 } catch (InvalidStatusException e) {
71 logger.warn("Api client error with status{}: {}", e.getStatus(), e.getMessage());
72 } catch (ApiClientException e) {
73 logger.warn("Api client error: {}", e.getMessage());
77 public void discoverDevice(SessionInfo info) {
78 var id = info.getDeviceId();
80 logger.warn("missing device id aborting");
83 var bridgeHandler = this.bridgeHandler;
84 if (bridgeHandler == null) {
85 logger.warn("missing bridge aborting");
88 logger.debug("Client discovered: [{}] {}", id, info.getDeviceName());
89 var bridgeUID = bridgeHandler.getThing().getUID();
90 Map<String, Object> properties = new HashMap<>();
91 properties.put(Thing.PROPERTY_SERIAL_NUMBER, id);
92 var appVersion = info.getApplicationVersion();
93 if (appVersion != null) {
94 properties.put(Thing.PROPERTY_FIRMWARE_VERSION, appVersion);
96 var client = info.getApplicationVersion();
98 properties.put(Thing.PROPERTY_VENDOR, client);
101 DiscoveryResultBuilder.create(new ThingUID(THING_TYPE_CLIENT, bridgeUID, id)).withBridge(bridgeUID)
102 .withTTL(DISCOVERY_RESULT_TTL_SEC).withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER)
103 .withProperties(properties).withLabel(info.getDeviceName()).build());
107 public void setThingHandler(ThingHandler thingHandler) {
108 if (thingHandler instanceof JellyfinServerHandler bridgeHandler) {
109 this.bridgeHandler = bridgeHandler;
114 public @Nullable ThingHandler getThingHandler() {
119 public void activate() {
120 activate(new HashMap<>());
124 public void deactivate() {