]> git.basschouten.com Git - openhab-addons.git/blob
33a81c21ffd2b0d07fc7d081cbda95a0822bd396
[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.mecmeter.internal.discovery;
14
15 import static org.openhab.binding.mecmeter.MecMeterBindingConstants.THING_TYPE_METER;
16
17 import java.net.InetAddress;
18 import java.util.HashMap;
19 import java.util.Map;
20 import java.util.Set;
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23
24 import javax.jmdns.ServiceInfo;
25
26 import org.eclipse.jdt.annotation.NonNullByDefault;
27 import org.eclipse.jdt.annotation.Nullable;
28 import org.openhab.binding.mecmeter.MecMeterBindingConstants;
29 import org.openhab.core.config.discovery.DiscoveryResult;
30 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
31 import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
32 import org.openhab.core.thing.Thing;
33 import org.openhab.core.thing.ThingTypeUID;
34 import org.openhab.core.thing.ThingUID;
35 import org.osgi.service.component.annotations.Component;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * The {@link MecMeterDiscoveryParticipant} is responsible for discovering devices, which are
41  * sent to inbox.
42  *
43  * @author Florian Pazour - Initial contribution
44  * @author Klaus Berger - Initial contribution
45  * @author Kai Kreuzer - Refactoring for openHAB 3
46  */
47 @NonNullByDefault
48 @Component(service = MDNSDiscoveryParticipant.class)
49 public class MecMeterDiscoveryParticipant implements MDNSDiscoveryParticipant {
50
51     private Logger logger = LoggerFactory.getLogger(MecMeterDiscoveryParticipant.class);
52     private static final String SERVICE_TYPE = "_http._tcp.local.";
53
54     /**
55      * Match the serial number, vendor and model of the discovered PowerMeter.
56      * Input is like "vpmAA11BB33CC55"
57      */
58     private static final Pattern MECMETER_PATTERN = Pattern
59             .compile("^(vpm|mec)[A-F0-9]{12}\\._http\\._tcp\\.local\\.$");
60
61     @Override
62     public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
63         return MecMeterBindingConstants.SUPPORTED_THING_TYPES_UIDS;
64     }
65
66     @Override
67     public String getServiceType() {
68         return SERVICE_TYPE;
69     }
70
71     @Override
72     public @Nullable DiscoveryResult createResult(ServiceInfo service) {
73         String qualifiedName = service.getQualifiedName();
74         logger.debug("Device found: {}", qualifiedName);
75         ThingUID uid = getThingUID(service);
76         if (uid == null) {
77             return null;
78         }
79
80         String serial = qualifiedName.substring(3, 15);
81         String vendor = "MEC";
82
83         InetAddress ip = getIpAddress(service);
84         if (ip == null) {
85             return null;
86         }
87         String inetAddress = ip.toString().substring(1);
88
89         Map<String, Object> properties = new HashMap<>(3);
90         properties.put(Thing.PROPERTY_SERIAL_NUMBER, serial);
91         properties.put(Thing.PROPERTY_VENDOR, vendor);
92         properties.put("ip", inetAddress);
93
94         String label = "MEC Power Meter";
95         return DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label)
96                 .withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER).build();
97     }
98
99     private @Nullable InetAddress getIpAddress(ServiceInfo service) {
100         if (service.getInet4Addresses().length > 0) {
101             return service.getInet4Addresses()[0];
102         } else {
103             return null;
104         }
105     }
106
107     @Override
108     public @Nullable ThingUID getThingUID(ServiceInfo service) {
109         Matcher matcher = MECMETER_PATTERN.matcher(service.getQualifiedName());
110         if (matcher.matches()) {
111             String serial = service.getQualifiedName().substring(3, 15); // Qualified Name like "mecABCDEF123456", we
112                                                                          // want "ABCDEF123456"
113             return new ThingUID(THING_TYPE_METER, serial);
114         } else {
115             logger.debug("The discovered device is not supported, ignoring it.");
116         }
117         return null;
118     }
119 }