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.kodi.internal.discovery;
15 import static org.openhab.binding.kodi.internal.KodiBindingConstants.*;
17 import java.util.Dictionary;
18 import java.util.HashMap;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.jupnp.model.meta.RemoteDevice;
25 import org.openhab.core.config.discovery.DiscoveryResult;
26 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
27 import org.openhab.core.config.discovery.upnp.UpnpDiscoveryParticipant;
28 import org.openhab.core.thing.ThingTypeUID;
29 import org.openhab.core.thing.ThingUID;
30 import org.osgi.service.component.ComponentContext;
31 import org.osgi.service.component.annotations.Activate;
32 import org.osgi.service.component.annotations.Component;
33 import org.osgi.service.component.annotations.Modified;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 * An UpnpDiscoveryParticipant which allows to discover Kodi AVRs.
40 * @author Paul Frank - Initial contribution
41 * @author Christoph Weitkamp - Use "discovery.kodi:background=false" to disable discovery service
43 @Component(configurationPid = "discovery.kodi")
45 public class KodiUpnpDiscoveryParticipant implements UpnpDiscoveryParticipant {
47 private Logger logger = LoggerFactory.getLogger(KodiUpnpDiscoveryParticipant.class);
49 private boolean isAutoDiscoveryEnabled = true;
52 protected void activate(ComponentContext componentContext) {
53 activateOrModifyService(componentContext);
57 protected void modified(ComponentContext componentContext) {
58 activateOrModifyService(componentContext);
61 private void activateOrModifyService(ComponentContext componentContext) {
62 Dictionary<String, @Nullable Object> properties = componentContext.getProperties();
63 String autoDiscoveryPropertyValue = (String) properties.get("background");
64 if (autoDiscoveryPropertyValue != null && !autoDiscoveryPropertyValue.isEmpty()) {
65 isAutoDiscoveryEnabled = Boolean.valueOf(autoDiscoveryPropertyValue);
70 public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
71 return SUPPORTED_THING_TYPES_UIDS;
75 public @Nullable DiscoveryResult createResult(RemoteDevice device) {
76 if (isAutoDiscoveryEnabled) {
77 ThingUID thingUid = getThingUID(device);
78 if (thingUid != null) {
79 String friendlyName = device.getDetails().getFriendlyName();
80 String label = friendlyName == null || friendlyName.isEmpty() ? device.getDisplayString()
82 Map<String, Object> properties = new HashMap<>();
83 properties.put(HOST_PARAMETER, device.getIdentity().getDescriptorURL().getHost());
85 DiscoveryResult result = DiscoveryResultBuilder.create(thingUid).withLabel(label)
86 .withProperties(properties).withRepresentationProperty(HOST_PARAMETER).build();
95 public @Nullable ThingUID getThingUID(RemoteDevice device) {
96 String manufacturer = device.getDetails().getManufacturerDetails().getManufacturer();
97 if (containsIgnoreCase(manufacturer, MANUFACTURER)) {
98 logger.debug("Manufacturer matched: search: {}, device value: {}.", MANUFACTURER, manufacturer);
99 String type = device.getType().getType();
100 if (containsIgnoreCase(type, UPNP_DEVICE_TYPE)) {
101 logger.debug("Device type matched: search: {}, device value: {}.", UPNP_DEVICE_TYPE, type);
102 return new ThingUID(THING_TYPE_KODI, device.getIdentity().getUdn().getIdentifierString());
108 private boolean containsIgnoreCase(final @Nullable String str, final String searchStr) {
109 return str != null && str.toLowerCase().contains(searchStr.toLowerCase());