Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RFC2217 discovery using mDNS #1388

Open
wants to merge 3 commits into
base: 2.5.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package org.openhab.binding.zwave.discovery;

import static java.util.Arrays.asList;
import static org.openhab.binding.zwave.ZWaveBindingConstants.*;

import java.util.HashSet;
import java.util.Set;

import javax.jmdns.ServiceInfo;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.config.discovery.DiscoveryResult;
import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder;
import org.eclipse.smarthome.config.discovery.mdns.MDNSDiscoveryParticipant;
import org.eclipse.smarthome.config.discovery.mdns.internal.MDNSDiscoveryService;
import org.eclipse.smarthome.core.thing.ThingTypeUID;
import org.eclipse.smarthome.core.thing.ThingUID;
import org.osgi.service.component.annotations.Component;

/**
* The {@link ZWaveRFC2217DiscoveryParticipant} is responsible for discovering remote ZWave controllers that are
* available through RFC2217. It uses {@link MDNSDiscoveryService}.
*
* @author Aitor Iturrioz - Initial contribution
*
*/
@Component(service = MDNSDiscoveryParticipant.class, immediate = true)
@NonNullByDefault
public class ZWaveRFC2217DiscoveryParticipant implements MDNSDiscoveryParticipant {

private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(asList(CONTROLLER_SERIAL));

public static final String ZWAVE_CONTROLLER_VENDOR_ID = "10c4";
public static final String ZWAVE_CONTROLLER_MODEL_ID = "ea60";
public static final String ZWAVE_CONTROLLER_DEFAULT_LABEL = "ZWave RFC2217 Controler";

public static final String ZWAVE_PLUS_CONTROLLER_VENDOR_ID = "0658";
public static final String ZWAVE_PLUS_CONTROLLER_MODEL_ID = "0200";
public static final String ZWAVE_PLUS_CONTROLLER_DEFAULT_LABEL = "ZWave Plus RFC2217 Controller";

private static final String SERVICE_TYPE = "_rfc2217._tcp.local.";

@Override
public Set<@NonNull ThingTypeUID> getSupportedThingTypeUIDs() {
return SUPPORTED_THING_TYPES;
}

@Override
public String getServiceType() {
return SERVICE_TYPE;
}

@Override
public @Nullable DiscoveryResult createResult(ServiceInfo service) {
ThingUID thingUID = getThingUID(service);
if (thingUID != null) {
String homeId = service.getPropertyString("HOME_ID");
String ipAddress = service.getHostAddresses()[0];
int port = service.getPort();
String port_id = String.format("rfc2217://%s:%d", ipAddress, port);

String label = String.format("%s (%s)",
isZWaveController(service) ? ZWAVE_CONTROLLER_DEFAULT_LABEL : ZWAVE_PLUS_CONTROLLER_DEFAULT_LABEL,
ipAddress);

DiscoveryResultBuilder discoveryResult = DiscoveryResultBuilder.create(thingUID)
.withProperty(CONFIGURATION_PORT, port_id).withLabel(label);

if (homeId != null) {
discoveryResult.withProperty(PROPERTY_HOMEID, homeId).withRepresentationProperty(PROPERTY_HOMEID);
}

return discoveryResult.build();
}
return null;

}

@Override
public @Nullable ThingUID getThingUID(ServiceInfo service) {
if (service.getType() != null && service.getType().equals(getServiceType())) {
if (isZWaveController(service) || isZWavePlusController(service)) {
String ipAddress = getIPAddress(service);
if (ipAddress != null) {
String homeId = service.getPropertyString("HOME_ID");
String ipAddressLastOctet = getIPAddressLastOctet(ipAddress);
String id = String.format("%s%s%s", service.getPropertyString("VENDOR_ID"),
service.getPropertyString("MODEL_ID"), ipAddressLastOctet);

if (homeId != null) {
id = homeId;
}

return new ThingUID(CONTROLLER_SERIAL, id);
}
}
}
return null;
}

private boolean isZWaveController(ServiceInfo service) {
return ZWAVE_CONTROLLER_VENDOR_ID.equals(service.getPropertyString("VENDOR_ID"))
&& ZWAVE_CONTROLLER_MODEL_ID.equals(service.getPropertyString("MODEL_ID"));
}

private boolean isZWavePlusController(ServiceInfo service) {
return ZWAVE_PLUS_CONTROLLER_VENDOR_ID.equals(service.getPropertyString("VENDOR_ID"))
&& ZWAVE_PLUS_CONTROLLER_MODEL_ID.equals(service.getPropertyString("MODEL_ID"));
}

private @Nullable String getIPAddress(ServiceInfo service) {
if (service.getHostAddresses() != null && service.getHostAddresses().length > 0
&& !service.getHostAddresses()[0].isEmpty()) {
return service.getHostAddresses()[0];
}
return null;
}

/**
* Get the last octet from an IP address.
* For example, for "192.168.1.15", "15" will be returned.
*/
private String getIPAddressLastOctet(String ipAddress) {
String[] ipAddressChunk = ipAddress.split("\\.");
return ipAddressChunk[ipAddressChunk.length - 1];

}
}
2 changes: 2 additions & 0 deletions src/main/resources/ESH-INF/thing/controller_serial.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
<channel id="serial_cse" typeId="serial_cse" />
</channels>

<representation-property>zwave_homeid</representation-property>

<config-description>
<parameter-group name="port">
<label>Port Configuration</label>
Expand Down