]> git.basschouten.com Git - openhab-addons.git/blob
1aad236ae4823ce8f37dd2556e37eb6a57b8700f
[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.binding.chromecast.internal.discovery;
14
15 import static org.openhab.binding.chromecast.internal.ChromecastBindingConstants.*;
16
17 import java.util.Dictionary;
18 import java.util.Map;
19 import java.util.Set;
20
21 import javax.jmdns.ServiceInfo;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.core.config.discovery.DiscoveryResult;
26 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
27 import org.openhab.core.config.discovery.DiscoveryService;
28 import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
29 import org.openhab.core.thing.ThingTypeUID;
30 import org.openhab.core.thing.ThingUID;
31 import org.osgi.service.component.ComponentContext;
32 import org.osgi.service.component.annotations.Activate;
33 import org.osgi.service.component.annotations.Component;
34 import org.osgi.service.component.annotations.Modified;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 /**
39  * The {@link ChromecastDiscoveryParticipant} is responsible for discovering Chromecast devices through mDNS.
40  *
41  * @author Kai Kreuzer - Initial contribution
42  * @author Daniel Walters - Change discovery protocol to mDNS
43  * @author Christoph Weitkamp - Use "discovery.chromecast:background=false" to disable discovery service
44  */
45 @Component(configurationPid = "discovery.chromecast")
46 @NonNullByDefault
47 public class ChromecastDiscoveryParticipant implements MDNSDiscoveryParticipant {
48
49     private final Logger logger = LoggerFactory.getLogger(ChromecastDiscoveryParticipant.class);
50
51     private static final String PROPERTY_MODEL = "md";
52     private static final String PROPERTY_FRIENDLY_NAME = "fn";
53     private static final String PROPERTY_DEVICE_ID = "id";
54     private static final String SERVICE_TYPE = "_googlecast._tcp.local.";
55
56     private boolean isAutoDiscoveryEnabled = true;
57
58     @Activate
59     protected void activate(ComponentContext componentContext) {
60         activateOrModifyService(componentContext);
61     }
62
63     @Modified
64     protected void modified(ComponentContext componentContext) {
65         activateOrModifyService(componentContext);
66     }
67
68     private void activateOrModifyService(ComponentContext componentContext) {
69         Dictionary<String, @Nullable Object> properties = componentContext.getProperties();
70         String autoDiscoveryPropertyValue = (String) properties
71                 .get(DiscoveryService.CONFIG_PROPERTY_BACKGROUND_DISCOVERY);
72         if (autoDiscoveryPropertyValue != null && !autoDiscoveryPropertyValue.isBlank()) {
73             isAutoDiscoveryEnabled = Boolean.valueOf(autoDiscoveryPropertyValue);
74         }
75     }
76
77     @Override
78     public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
79         return SUPPORTED_THING_TYPES_UIDS;
80     }
81
82     @Override
83     public String getServiceType() {
84         return SERVICE_TYPE;
85     }
86
87     @Override
88     public @Nullable DiscoveryResult createResult(ServiceInfo service) {
89         if (isAutoDiscoveryEnabled) {
90             ThingUID uid = getThingUID(service);
91             if (uid != null) {
92                 String host = service.getHostAddresses()[0];
93                 int port = service.getPort();
94                 logger.debug("Chromecast Found: {} {}", host, port);
95                 String id = service.getPropertyString(PROPERTY_DEVICE_ID);
96                 String friendlyName = service.getPropertyString(PROPERTY_FRIENDLY_NAME); // friendly name;
97                 return DiscoveryResultBuilder.create(uid).withThingType(getThingType(service))
98                         .withProperties(Map.of(HOST, host, PORT, port, DEVICE_ID, id))
99                         .withRepresentationProperty(DEVICE_ID).withLabel(friendlyName).build();
100             }
101         }
102         return null;
103     }
104
105     private @Nullable ThingTypeUID getThingType(final ServiceInfo service) {
106         String model = service.getPropertyString(PROPERTY_MODEL); // model
107         logger.debug("Chromecast Type: {}", model);
108         if (model == null) {
109             return null;
110         }
111         switch (model) {
112             case "Chromecast Audio":
113                 return THING_TYPE_AUDIO;
114             case "Google Cast Group":
115                 return THING_TYPE_AUDIOGROUP;
116             default:
117                 return THING_TYPE_CHROMECAST;
118         }
119     }
120
121     @Override
122     public @Nullable ThingUID getThingUID(ServiceInfo service) {
123         ThingTypeUID thingTypeUID = getThingType(service);
124         if (thingTypeUID != null) {
125             String id = service.getPropertyString(PROPERTY_DEVICE_ID); // device id
126             return new ThingUID(thingTypeUID, id);
127         }
128         return null;
129     }
130 }