]> git.basschouten.com Git - openhab-addons.git/blob
2c381af818a4b10c56dda9f6c3726b97019387df
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.avmfritz.internal.discovery;
14
15 import static org.openhab.binding.avmfritz.internal.AVMFritzBindingConstants.*;
16 import static org.openhab.core.thing.Thing.PROPERTY_VENDOR;
17
18 import java.util.Dictionary;
19 import java.util.Map;
20 import java.util.Set;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.jupnp.model.meta.DeviceDetails;
25 import org.jupnp.model.meta.ModelDetails;
26 import org.jupnp.model.meta.RemoteDevice;
27 import org.openhab.core.config.discovery.DiscoveryResult;
28 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
29 import org.openhab.core.config.discovery.upnp.UpnpDiscoveryParticipant;
30 import org.openhab.core.config.discovery.upnp.internal.UpnpDiscoveryService;
31 import org.openhab.core.thing.ThingTypeUID;
32 import org.openhab.core.thing.ThingUID;
33 import org.osgi.service.component.ComponentContext;
34 import org.osgi.service.component.annotations.Activate;
35 import org.osgi.service.component.annotations.Component;
36 import org.osgi.service.component.annotations.Modified;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * The {@link AVMFritzUpnpDiscoveryParticipant} is responsible for discovering new and removed FRITZ!Box devices. It
42  * uses the central {@link UpnpDiscoveryService}.
43  *
44  * @author Robert Bausdorf - Initial contribution
45  * @author Christoph Weitkamp - Added support for groups
46  * @author Christoph Weitkamp - Use "discovery.avmfritz:background=false" to disable discovery service
47  */
48 @Component(configurationPid = "discovery.avmfritz")
49 @NonNullByDefault
50 public class AVMFritzUpnpDiscoveryParticipant implements UpnpDiscoveryParticipant {
51
52     private final Logger logger = LoggerFactory.getLogger(AVMFritzUpnpDiscoveryParticipant.class);
53
54     private boolean isAutoDiscoveryEnabled = true;
55
56     @Activate
57     protected void activate(ComponentContext componentContext) {
58         activateOrModifyService(componentContext);
59     }
60
61     @Modified
62     protected void modified(ComponentContext componentContext) {
63         activateOrModifyService(componentContext);
64     }
65
66     private void activateOrModifyService(ComponentContext componentContext) {
67         Dictionary<String, @Nullable Object> properties = componentContext.getProperties();
68         String autoDiscoveryPropertyValue = (String) properties.get("background");
69         if (autoDiscoveryPropertyValue != null && autoDiscoveryPropertyValue.length() != 0) {
70             isAutoDiscoveryEnabled = Boolean.valueOf(autoDiscoveryPropertyValue);
71         }
72     }
73
74     @Override
75     public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
76         return SUPPORTED_BRIDGE_THING_TYPES_UIDS;
77     }
78
79     @Override
80     public @Nullable DiscoveryResult createResult(RemoteDevice device) {
81         if (isAutoDiscoveryEnabled) {
82             ThingUID uid = getThingUID(device);
83             if (uid != null) {
84                 logger.debug("discovered: {} ({}) at {}", device.getDisplayString(),
85                         device.getDetails().getFriendlyName(), device.getIdentity().getDescriptorURL().getHost());
86                 return DiscoveryResultBuilder.create(uid)
87                         .withProperties(Map.of(CONFIG_IP_ADDRESS, device.getIdentity().getDescriptorURL().getHost(),
88                                 PROPERTY_VENDOR, device.getDetails().getManufacturerDetails().getManufacturer()))
89                         .withLabel(device.getDetails().getFriendlyName()).withRepresentationProperty(CONFIG_IP_ADDRESS)
90                         .build();
91             }
92         }
93         return null;
94     }
95
96     @Override
97     public @Nullable ThingUID getThingUID(RemoteDevice device) {
98         // newer FRITZ!OS versions return several upnp services (e.g. Mediaserver)
99         if (device.getType().getType().equals(BRIDGE_FRITZBOX)) {
100             DeviceDetails details = device.getDetails();
101             if (details != null) {
102                 ModelDetails modelDetails = details.getModelDetails();
103                 if (modelDetails != null) {
104                     String modelName = modelDetails.getModelName();
105                     if (modelName != null) {
106                         // It would be better to use udn but in my case FB is discovered twice
107                         // .getIdentity().getUdn().getIdentifierString()
108                         String id = device.getIdentity().getDescriptorURL().getHost().replaceAll(INVALID_PATTERN, "_");
109                         if (modelName.startsWith(BOX_MODEL_NAME)) {
110                             logger.debug("discovered on {}", device.getIdentity().getDiscoveredOnLocalAddress());
111                             return new ThingUID(BRIDGE_THING_TYPE, id);
112                         } else if (POWERLINE546E_MODEL_NAME.equals(modelName)) {
113                             logger.debug("discovered on {}", device.getIdentity().getDiscoveredOnLocalAddress());
114                             return new ThingUID(POWERLINE546E_STANDALONE_THING_TYPE, id);
115                         }
116                     }
117                 }
118             }
119         }
120         return null;
121     }
122 }