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.mecmeter.internal.discovery;
15 import static org.openhab.binding.mecmeter.MecMeterBindingConstants.THING_TYPE_METER;
17 import java.net.InetAddress;
18 import java.util.HashMap;
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
24 import javax.jmdns.ServiceInfo;
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;
40 * The {@link MecMeterDiscoveryParticipant} is responsible for discovering devices, which are
43 * @author Florian Pazour - Initial contribution
44 * @author Klaus Berger - Initial contribution
45 * @author Kai Kreuzer - Refactoring for openHAB 3
48 @Component(service = MDNSDiscoveryParticipant.class)
49 public class MecMeterDiscoveryParticipant implements MDNSDiscoveryParticipant {
51 private Logger logger = LoggerFactory.getLogger(MecMeterDiscoveryParticipant.class);
52 private static final String SERVICE_TYPE = "_http._tcp.local.";
55 * Match the serial number, vendor and model of the discovered PowerMeter.
56 * Input is like "vpmAA11BB33CC55"
58 private static final Pattern MECMETER_PATTERN = Pattern
59 .compile("^(vpm|mec)[A-F0-9]{12}\\._http\\._tcp\\.local\\.$");
62 public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
63 return MecMeterBindingConstants.SUPPORTED_THING_TYPES_UIDS;
67 public String getServiceType() {
72 public @Nullable DiscoveryResult createResult(ServiceInfo service) {
73 String qualifiedName = service.getQualifiedName();
74 logger.debug("Device found: {}", qualifiedName);
75 ThingUID uid = getThingUID(service);
80 String serial = qualifiedName.substring(3, 15);
81 String vendor = "MEC";
83 InetAddress ip = getIpAddress(service);
87 String inetAddress = ip.toString().substring(1);
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);
94 String label = "MEC Power Meter";
95 return DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label)
96 .withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER).build();
99 private @Nullable InetAddress getIpAddress(ServiceInfo service) {
100 if (service.getInet4Addresses().length > 0) {
101 return service.getInet4Addresses()[0];
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);
115 logger.debug("The discovered device is not supported, ignoring it.");