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

[miele] Refactor mDNS discovery #11873

Merged
merged 2 commits into from
Dec 28, 2021
Merged
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
Expand Up @@ -15,19 +15,19 @@
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.jmdns.ServiceInfo;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.miele.internal.MieleBindingConstants;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler;
import org.openhab.core.config.discovery.DiscoveryResult;
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
import org.openhab.core.config.discovery.mdns.internal.MDNSDiscoveryService;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
import org.osgi.service.component.annotations.Activate;
Expand All @@ -44,23 +44,32 @@
* @author Martin Lepsy - Added check for Miele gateway for cleaner discovery
* @author Jacob Laursen - Fixed multicast and protocol support (ZigBee/LAN)
*/
@NonNullByDefault
@Component(configurationPid = "discovery.miele")
public class MieleMDNSDiscoveryParticipant implements MDNSDiscoveryParticipant {

private final Logger logger = LoggerFactory.getLogger(MieleMDNSDiscoveryParticipant.class);
private static final String SERVICE_TYPE = "_mieleathome._tcp.local.";
private static final String PATH_TO_CHECK_FOR_XGW3000 = "/rest/";
private static final String SERVICE_NAME = "mieleathome";
private static final String PATH_PROPERTY_NAME = "path";

private final Logger logger = LoggerFactory.getLogger(MieleMDNSDiscoveryParticipant.class);

private long removalGracePeriodSeconds = 15;

@Activate
public void activate(@Nullable Map<String, Object> configProperties) {
if (configProperties == null) {
return;
}
updateRemovalGracePeriod(configProperties);
}

@Modified
public void modified(@Nullable Map<String, Object> configProperties) {
if (configProperties == null) {
return;
}
updateRemovalGracePeriod(configProperties);
}

Expand All @@ -70,83 +79,88 @@ public void modified(@Nullable Map<String, Object> configProperties) {
* @param configProperties the passed configuration parameters.
*/
private void updateRemovalGracePeriod(Map<String, Object> configProperties) {
if (configProperties != null) {
Object value = configProperties.get(MieleBindingConstants.REMOVAL_GRACE_PERIOD);
if (value != null) {
try {
removalGracePeriodSeconds = Integer.parseInt(value.toString());
} catch (NumberFormatException e) {
logger.warn("Configuration property '{}' has invalid value: {}",
MieleBindingConstants.REMOVAL_GRACE_PERIOD, value);
}
Object value = configProperties.get(MieleBindingConstants.REMOVAL_GRACE_PERIOD);
if (value != null) {
try {
removalGracePeriodSeconds = Integer.parseInt(value.toString());
} catch (NumberFormatException e) {
logger.warn("Configuration property '{}' has invalid value: {}",
MieleBindingConstants.REMOVAL_GRACE_PERIOD, value);
}
}
}

@Override
public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
return Collections.singleton(MieleBindingConstants.THING_TYPE_XGW3000);
return MieleBridgeHandler.SUPPORTED_THING_TYPES;
}

@Override
public String getServiceType() {
return "_mieleathome._tcp.local.";
return SERVICE_TYPE;
}

@Override
public DiscoveryResult createResult(ServiceInfo service) {
if (isMieleGateway(service)) {
ThingUID uid = getThingUID(service);

if (uid != null) {
Map<String, Object> properties = new HashMap<>(2);

InetAddress[] addresses = service.getInetAddresses();
if (addresses.length > 0 && addresses[0] != null) {
properties.put(MieleBindingConstants.HOST, addresses[0].getHostAddress());

Socket socket = null;
try {
socket = new Socket(addresses[0], 80);
InetAddress ourAddress = socket.getLocalAddress();
properties.put(MieleBindingConstants.INTERFACE, ourAddress.getHostAddress());
} catch (IOException e) {
logger.error("An exception occurred while connecting to the Miele Gateway : '{}'",
e.getMessage());
}
}

return DiscoveryResultBuilder.create(uid).withProperties(properties)
.withRepresentationProperty(MieleBindingConstants.HOST).withLabel("Miele XGW3000").build();
}
public @Nullable DiscoveryResult createResult(ServiceInfo service) {
if (!isMieleGateway(service)) {
return null;
}
return null;

ThingUID uid = getThingUID(service);
if (uid == null) {
return null;
}

InetAddress[] addresses = service.getInetAddresses();
if (addresses.length <= 0 || addresses[0] == null) {
return null;
}

String ipAddress = addresses[0].getHostAddress();
Map<String, Object> properties = new HashMap<>(2);
properties.put(MieleBindingConstants.HOST, ipAddress);

Socket socket = null;
try {
socket = new Socket(addresses[0], 80);
InetAddress ourAddress = socket.getLocalAddress();
String interfaceIpAddress = ourAddress.getHostAddress();
socket.close();

properties.put(MieleBindingConstants.INTERFACE, interfaceIpAddress);
logger.debug("Discovered Miele@home gateway with IP address {} and interface IP address {}", ipAddress,
interfaceIpAddress);
} catch (IOException e) {
logger.warn("An exception occurred while connecting to the Miele Gateway: '{}'", e.getMessage());
return null;
}

return DiscoveryResultBuilder.create(uid).withProperties(properties)
.withRepresentationProperty(MieleBindingConstants.HOST).withLabel("@text/discovery.xgw3000.label")
.build();
}

@Override
public ThingUID getThingUID(ServiceInfo service) {
if (service.getType() != null) {
if (service.getType().equals(getServiceType())) {
logger.trace("Discovered a Miele@Home gateway thing with name '{}'", service.getName());
return new ThingUID(MieleBindingConstants.THING_TYPE_XGW3000, service.getName().replace(" ", "_"));
}
public @Nullable ThingUID getThingUID(ServiceInfo service) {
if (SERVICE_TYPE.equals(service.getType())) {
return new ThingUID(MieleBindingConstants.THING_TYPE_XGW3000, service.getName().replace(" ", "_"));
}

return null;
}

/**
* Checks if service is a Miele XGW3000 Gateway
* Checks if service is a Miele XGW 3000 Gateway
*
* application must be mieleathome
* must contain path with value /rest/
*
* @param service the service to check
* @return true, if the discovered service is a Miele XGW3000 Gateway
*/
private boolean isMieleGateway(ServiceInfo service) {
return service.getApplication().contains(SERVICE_NAME) && service.getPropertyString(PATH_PROPERTY_NAME) != null
&& service.getPropertyString(PATH_PROPERTY_NAME).equalsIgnoreCase(PATH_TO_CHECK_FOR_XGW3000);
private boolean isMieleGateway(ServiceInfo serviceInfo) {
return serviceInfo.getApplication().contains(SERVICE_NAME)
&& PATH_TO_CHECK_FOR_XGW3000.equalsIgnoreCase(serviceInfo.getPropertyString(PATH_PROPERTY_NAME));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ offline.configuration-error.invalid-ip-gateway = Invalid IP address for the Miel
offline.configuration-error.invalid-ip-multicast-interface = Invalid IP address for the multicast interface: {0}
offline.configuration-error.invalid-language = Invalid language: {0}

# Discovery result

discovery.xgw3000.label = Miele XGW 3000

# miele states

miele.state.off = Off
Expand Down