Skip to content

Commit eb6a56d

Browse files
authored
[hdpowerview] Fix discovery to use serial number as representation property (openhab#18200)
Signed-off-by: Andrew Fiddian-Green <[email protected]>
1 parent 6a840f7 commit eb6a56d

File tree

6 files changed

+249
-78
lines changed

6 files changed

+249
-78
lines changed

bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java

+4
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,8 @@ public class HDPowerViewBindingConstants {
8787
public static final String PROPERTY_NAME = "name";
8888
public static final String PROPERTY_POWER_TYPE = "powerType";
8989
public static final String PROPERTY_BLE_NAME = "bleName";
90+
91+
// keys for hub/gateway label translation
92+
public static final String LABEL_KEY_HUB = "discovery.hub.label";
93+
public static final String LABEL_KEY_GATEWAY = "discovery.gateway.label";
9094
}

bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/GatewayDiscoveryParticipant.java

+23-11
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import static org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants.*;
1616

17+
import java.util.Arrays;
1718
import java.util.Set;
1819

1920
import javax.jmdns.ServiceInfo;
@@ -24,6 +25,7 @@
2425
import org.openhab.core.config.discovery.DiscoveryResult;
2526
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
2627
import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
28+
import org.openhab.core.thing.Thing;
2729
import org.openhab.core.thing.ThingTypeUID;
2830
import org.openhab.core.thing.ThingUID;
2931
import org.osgi.service.component.annotations.Component;
@@ -39,20 +41,21 @@
3941
@Component
4042
public class GatewayDiscoveryParticipant implements MDNSDiscoveryParticipant {
4143

42-
private static final String LABEL_KEY = "discovery.gateway.label";
43-
4444
private final Logger logger = LoggerFactory.getLogger(GatewayDiscoveryParticipant.class);
4545

4646
@Override
4747
public @Nullable DiscoveryResult createResult(ServiceInfo service) {
48-
for (String host : service.getHostAddresses()) {
49-
if (VALID_IP_V4_ADDRESS.matcher(host).matches()) {
50-
ThingUID thingUID = new ThingUID(THING_TYPE_GATEWAY, host.replace('.', '_'));
48+
ThingUID thingUID = getThingUID(service);
49+
if (thingUID != null) {
50+
String serial = thingUID.getId();
51+
String host = getIpV4Address(service);
52+
if (host != null) {
53+
String label = String.format("@text/%s [\"%s\"]", LABEL_KEY_GATEWAY, host);
5154
DiscoveryResult hub = DiscoveryResultBuilder.create(thingUID)
5255
.withProperty(HDPowerViewHubConfiguration.HOST, host)
53-
.withRepresentationProperty(HDPowerViewHubConfiguration.HOST)
54-
.withLabel(String.format("@text/%s [\"%s\"]", LABEL_KEY, host)).build();
55-
logger.debug("mDNS discovered Gen 3 gateway on host '{}'", host);
56+
.withProperty(Thing.PROPERTY_SERIAL_NUMBER, serial)
57+
.withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER).withLabel(label).build();
58+
logger.debug("mDNS discovered Gen 3 gateway '{}' on host '{}'", thingUID, host);
5659
return hub;
5760
}
5861
}
@@ -71,11 +74,20 @@ public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
7174

7275
@Override
7376
public @Nullable ThingUID getThingUID(ServiceInfo service) {
74-
for (String host : service.getHostAddresses()) {
75-
if (VALID_IP_V4_ADDRESS.matcher(host).matches()) {
76-
return new ThingUID(THING_TYPE_GATEWAY, host.replace('.', '_'));
77+
String host = getIpV4Address(service);
78+
if (host != null) {
79+
String serial = service.getPropertyString("sn");
80+
if (serial != null) {
81+
return new ThingUID(THING_TYPE_GATEWAY, serial);
82+
} else {
83+
logger.debug("Error discovering gateway 'missing serial number'");
7784
}
7885
}
7986
return null;
8087
}
88+
89+
private static @Nullable String getIpV4Address(ServiceInfo service) {
90+
return Arrays.stream(service.getHostAddresses()).filter(host -> VALID_IP_V4_ADDRESS.matcher(host).matches())
91+
.findFirst().orElse(null);
92+
}
8193
}

bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/HDPowerViewHubDiscoveryService.java

+17-7
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,16 @@
2222
import org.eclipse.jdt.annotation.NonNullByDefault;
2323
import org.eclipse.jdt.annotation.Nullable;
2424
import org.openhab.binding.hdpowerview.internal.config.HDPowerViewHubConfiguration;
25+
import org.openhab.binding.hdpowerview.internal.exceptions.HubException;
2526
import org.openhab.core.config.discovery.AbstractDiscoveryService;
2627
import org.openhab.core.config.discovery.DiscoveryResult;
2728
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
2829
import org.openhab.core.config.discovery.DiscoveryService;
30+
import org.openhab.core.thing.Thing;
2931
import org.openhab.core.thing.ThingUID;
32+
import org.osgi.service.component.annotations.Activate;
3033
import org.osgi.service.component.annotations.Component;
34+
import org.osgi.service.component.annotations.Reference;
3135
import org.slf4j.Logger;
3236
import org.slf4j.LoggerFactory;
3337

@@ -46,10 +50,13 @@ public class HDPowerViewHubDiscoveryService extends AbstractDiscoveryService {
4650

4751
private final Runnable scanner;
4852
private @Nullable ScheduledFuture<?> backgroundFuture;
53+
private final HDPowerviewPropertyGetter propertyGetter;
4954

50-
public HDPowerViewHubDiscoveryService() {
55+
@Activate
56+
public HDPowerViewHubDiscoveryService(@Reference HDPowerviewPropertyGetter propertyGetter) {
5157
super(Set.of(THING_TYPE_HUB), 60, true);
5258
scanner = createScanner();
59+
this.propertyGetter = propertyGetter;
5360
}
5461

5562
@Override
@@ -83,17 +90,20 @@ private Runnable createScanner() {
8390
NbtAddress address = NbtAddress.getByName(netBiosName);
8491
if (address != null) {
8592
String host = address.getInetAddress().getHostAddress();
86-
ThingUID thingUID = new ThingUID(THING_TYPE_HUB, host.replace('.', '_'));
93+
String serial = propertyGetter.getSerialNumberApiV1(host);
94+
ThingUID thingUID = new ThingUID(THING_TYPE_HUB, serial);
95+
String label = String.format("@text/%s [\"%s\", \"%s\"]", LABEL_KEY_HUB, "1", host);
8796
DiscoveryResult hub = DiscoveryResultBuilder.create(thingUID)
8897
.withProperty(HDPowerViewHubConfiguration.HOST, host)
89-
.withRepresentationProperty(HDPowerViewHubConfiguration.HOST)
90-
.withLabel("PowerView Hub (" + host + ")").build();
91-
logger.debug("NetBios discovered hub on host '{}'", host);
98+
.withProperty(Thing.PROPERTY_SERIAL_NUMBER, serial)
99+
.withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER).withLabel(label).build();
100+
logger.debug("NetBios discovered Gen 1 hub '{}' on host '{}'", thingUID, host);
92101
thingDiscovered(hub);
93102
}
103+
} catch (HubException e) {
104+
logger.debug("Error discovering hub", e);
94105
} catch (UnknownHostException e) {
95-
// Nothing to do here - the host couldn't be found, likely because it doesn't
96-
// exist
106+
// Nothing to do here - the host couldn't be found, likely because it doesn't exist
97107
}
98108
}
99109
};

bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/HDPowerViewHubMDNSDiscoveryParticipant.java

+31-32
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,19 @@
1414

1515
import static org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants.*;
1616

17+
import java.util.Arrays;
1718
import java.util.Set;
1819

1920
import javax.jmdns.ServiceInfo;
2021

2122
import org.eclipse.jdt.annotation.NonNullByDefault;
2223
import org.eclipse.jdt.annotation.Nullable;
23-
import org.eclipse.jetty.client.HttpClient;
24-
import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets;
2524
import org.openhab.binding.hdpowerview.internal.config.HDPowerViewHubConfiguration;
26-
import org.openhab.binding.hdpowerview.internal.dto.Firmware;
27-
import org.openhab.binding.hdpowerview.internal.dto.HubFirmware;
2825
import org.openhab.binding.hdpowerview.internal.exceptions.HubException;
2926
import org.openhab.core.config.discovery.DiscoveryResult;
3027
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
3128
import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
32-
import org.openhab.core.io.net.http.HttpClientFactory;
29+
import org.openhab.core.thing.Thing;
3330
import org.openhab.core.thing.ThingTypeUID;
3431
import org.openhab.core.thing.ThingUID;
3532
import org.osgi.service.component.annotations.Activate;
@@ -47,14 +44,13 @@
4744
@Component
4845
public class HDPowerViewHubMDNSDiscoveryParticipant implements MDNSDiscoveryParticipant {
4946

50-
public static final String LABEL_KEY_HUB = "discovery.hub.label";
51-
5247
private final Logger logger = LoggerFactory.getLogger(HDPowerViewHubMDNSDiscoveryParticipant.class);
53-
private final HttpClient httpClient;
48+
49+
private final HDPowerviewPropertyGetter propertyGetter;
5450

5551
@Activate
56-
public HDPowerViewHubMDNSDiscoveryParticipant(@Reference HttpClientFactory httpClientFactory) {
57-
httpClient = httpClientFactory.getCommonHttpClient();
52+
public HDPowerViewHubMDNSDiscoveryParticipant(@Reference HDPowerviewPropertyGetter propertyGetter) {
53+
this.propertyGetter = propertyGetter;
5854
}
5955

6056
@Override
@@ -69,15 +65,23 @@ public String getServiceType() {
6965

7066
@Override
7167
public @Nullable DiscoveryResult createResult(ServiceInfo service) {
72-
for (String host : service.getHostAddresses()) {
73-
if (VALID_IP_V4_ADDRESS.matcher(host).matches()) {
74-
ThingUID thingUID = new ThingUID(THING_TYPE_HUB, host.replace('.', '_'));
75-
String generation = this.getGeneration(host);
68+
ThingUID thingUID = getThingUID(service);
69+
if (thingUID != null) {
70+
String serial = thingUID.getId();
71+
String host = getIpV4Address(service);
72+
if (host != null) {
73+
String generation;
74+
try {
75+
generation = propertyGetter.getGenerationApiV1(host);
76+
} catch (HubException e) {
77+
generation = "1/2";
78+
}
79+
String label = String.format("@text/%s [\"%s\", \"%s\"]", LABEL_KEY_HUB, generation, host);
7680
DiscoveryResult hub = DiscoveryResultBuilder.create(thingUID)
7781
.withProperty(HDPowerViewHubConfiguration.HOST, host)
78-
.withRepresentationProperty(HDPowerViewHubConfiguration.HOST)
79-
.withLabel(String.format("@text/%s [\"%s\", \"%s\"]", LABEL_KEY_HUB, generation, host)).build();
80-
logger.debug("mDNS discovered Gen {} hub on host '{}'", generation, host);
82+
.withProperty(Thing.PROPERTY_SERIAL_NUMBER, serial)
83+
.withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER).withLabel(label).build();
84+
logger.debug("mDNS discovered Gen {} hub '{}' on host '{}'", generation, thingUID, host);
8185
return hub;
8286
}
8387
}
@@ -86,25 +90,20 @@ public String getServiceType() {
8690

8791
@Override
8892
public @Nullable ThingUID getThingUID(ServiceInfo service) {
89-
for (String host : service.getHostAddresses()) {
90-
if (VALID_IP_V4_ADDRESS.matcher(host).matches()) {
91-
return new ThingUID(THING_TYPE_HUB, host.replace('.', '_'));
93+
String host = getIpV4Address(service);
94+
if (host != null) {
95+
try {
96+
String serial = propertyGetter.getSerialNumberApiV1(host);
97+
return new ThingUID(THING_TYPE_HUB, serial);
98+
} catch (HubException e) {
99+
logger.debug("Error discovering hub", e);
92100
}
93101
}
94102
return null;
95103
}
96104

97-
private String getGeneration(String host) {
98-
var webTargets = new HDPowerViewWebTargets(httpClient, host);
99-
try {
100-
HubFirmware firmware = webTargets.getFirmwareVersions();
101-
Firmware mainProcessor = firmware.mainProcessor;
102-
if (mainProcessor != null) {
103-
return String.valueOf(mainProcessor.revision);
104-
}
105-
} catch (HubException e) {
106-
logger.debug("Failed to discover hub firmware versions", e);
107-
}
108-
return "1/2";
105+
private static @Nullable String getIpV4Address(ServiceInfo service) {
106+
return Arrays.stream(service.getHostAddresses()).filter(host -> VALID_IP_V4_ADDRESS.matcher(host).matches())
107+
.findFirst().orElse(null);
109108
}
110109
}

bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/HDPowerViewSddpDiscoveryParticipant.java

+35-28
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@
1919
import org.eclipse.jdt.annotation.NonNullByDefault;
2020
import org.eclipse.jdt.annotation.Nullable;
2121
import org.openhab.binding.hdpowerview.internal.config.HDPowerViewHubConfiguration;
22+
import org.openhab.binding.hdpowerview.internal.exceptions.HubException;
2223
import org.openhab.core.config.discovery.DiscoveryResult;
2324
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
2425
import org.openhab.core.config.discovery.sddp.SddpDevice;
2526
import org.openhab.core.config.discovery.sddp.SddpDiscoveryParticipant;
27+
import org.openhab.core.thing.Thing;
2628
import org.openhab.core.thing.ThingTypeUID;
2729
import org.openhab.core.thing.ThingUID;
30+
import org.osgi.service.component.annotations.Activate;
2831
import org.osgi.service.component.annotations.Component;
32+
import org.osgi.service.component.annotations.Reference;
2933
import org.slf4j.Logger;
3034
import org.slf4j.LoggerFactory;
3135

@@ -38,53 +42,58 @@
3842
@Component
3943
public class HDPowerViewSddpDiscoveryParticipant implements SddpDiscoveryParticipant {
4044

41-
private static final String LABEL_KEY_GATEWAY = "discovery.gateway.label";
42-
4345
private static final String HUNTER_DOUGLAS = "hunterdouglas:";
4446
private static final String POWERVIEW_HUB_ID = "hub:powerview";
4547
private static final String POWERVIEW_GEN3_ID = "powerview:gen3:gateway";
4648

4749
private final Logger logger = LoggerFactory.getLogger(HDPowerViewSddpDiscoveryParticipant.class);
4850

51+
private final HDPowerviewPropertyGetter propertyGetter;
52+
53+
@Activate
54+
public HDPowerViewSddpDiscoveryParticipant(@Reference HDPowerviewPropertyGetter propertyGetter) {
55+
this.propertyGetter = propertyGetter;
56+
}
57+
4958
@Override
5059
public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
5160
return Set.of(THING_TYPE_HUB, THING_TYPE_GATEWAY);
5261
}
5362

5463
@Override
5564
public @Nullable DiscoveryResult createResult(SddpDevice device) {
56-
final ThingUID thingUID = getThingUID(device);
65+
ThingUID thingUID = getThingUID(device);
5766
if (thingUID != null) {
58-
try {
59-
int generation = getGeneration(device);
60-
String label = generation == 3 //
61-
? String.format("@text/%s [\"%s\"]", LABEL_KEY_GATEWAY, device.ipAddress)
62-
: String.format("@text/%s [\"%s\", \"%s\"]",
63-
HDPowerViewHubMDNSDiscoveryParticipant.LABEL_KEY_HUB, generation, device.ipAddress);
64-
65-
DiscoveryResult hub = DiscoveryResultBuilder.create(thingUID)
66-
.withProperty(HDPowerViewHubConfiguration.HOST, device.ipAddress)
67-
.withRepresentationProperty(HDPowerViewHubConfiguration.HOST).withLabel(label).build();
68-
logger.debug("SDDP discovered Gen {} hub/gateway '{}' on host '{}'", generation, thingUID,
69-
device.ipAddress);
70-
return hub;
71-
} catch (IllegalArgumentException e) {
72-
// error already logged, so fall through
73-
}
67+
String serial = thingUID.getId();
68+
String host = device.ipAddress;
69+
int generation = getGeneration(device);
70+
String label = generation < 3 //
71+
? String.format("@text/%s [\"%s\", \"%s\"]", LABEL_KEY_HUB, generation, host)
72+
: String.format("@text/%s [\"%s\"]", LABEL_KEY_GATEWAY, host);
73+
DiscoveryResult hub = DiscoveryResultBuilder.create(thingUID)
74+
.withProperty(HDPowerViewHubConfiguration.HOST, host)
75+
.withProperty(Thing.PROPERTY_SERIAL_NUMBER, serial)
76+
.withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER).withLabel(label).build();
77+
logger.debug("SDDP discovered Gen {} hub/gateway '{}' on host '{}'", generation, thingUID, host);
78+
return hub;
7479
}
7580
return null;
7681
}
7782

7883
@Override
7984
public @Nullable ThingUID getThingUID(SddpDevice device) {
8085
if (device.type.startsWith(HUNTER_DOUGLAS)) {
81-
try {
82-
if (VALID_IP_V4_ADDRESS.matcher(device.ipAddress).matches()) {
83-
return new ThingUID(getGeneration(device) == 3 ? THING_TYPE_GATEWAY : THING_TYPE_HUB,
84-
device.ipAddress.replace('.', '_'));
86+
String host = device.ipAddress;
87+
if (VALID_IP_V4_ADDRESS.matcher(host).matches()) {
88+
try {
89+
int generation = getGeneration(device);
90+
String serial = generation < 3 //
91+
? propertyGetter.getSerialNumberApiV1(host)
92+
: propertyGetter.getSerialNumberApiV3(host);
93+
return new ThingUID(generation < 3 ? THING_TYPE_HUB : THING_TYPE_GATEWAY, serial);
94+
} catch (HubException | IllegalArgumentException e) {
95+
logger.debug("Error discovering hub/gateway", e);
8596
}
86-
} catch (IllegalArgumentException e) {
87-
// error already logged, so fall through
8897
}
8998
}
9099
return null;
@@ -103,8 +112,6 @@ private int getGeneration(SddpDevice device) throws IllegalArgumentException {
103112
if (device.type.contains(POWERVIEW_HUB_ID)) {
104113
return device.type.endsWith("v2") ? 2 : 1;
105114
}
106-
final IllegalArgumentException e = new IllegalArgumentException("Device has unexpected 'type' property");
107-
logger.debug("{}", e.getMessage());
108-
throw e;
115+
throw new IllegalArgumentException("Device has unexpected 'type' property");
109116
}
110117
}

0 commit comments

Comments
 (0)