]> git.basschouten.com Git - openhab-addons.git/commitdiff
[asuswrt] Support router discovery and add-on suggestion using UPnP (#16084)
authorWouter Born <github@maindrain.net>
Sat, 23 Dec 2023 17:29:41 +0000 (18:29 +0100)
committerGitHub <noreply@github.com>
Sat, 23 Dec 2023 17:29:41 +0000 (18:29 +0100)
This makes it easier to discover the devices and the add-on.

Signed-off-by: Wouter Born <github@maindrain.net>
bundles/org.openhab.binding.asuswrt/README.md
bundles/org.openhab.binding.asuswrt/src/main/feature/feature.xml
bundles/org.openhab.binding.asuswrt/src/main/java/org/openhab/binding/asuswrt/internal/AsuswrtDiscoveryParticipant.java [new file with mode: 0644]
bundles/org.openhab.binding.asuswrt/src/main/java/org/openhab/binding/asuswrt/internal/constants/AsuswrtBindingConstants.java
bundles/org.openhab.binding.asuswrt/src/main/resources/OH-INF/addon/addon.xml
bundles/org.openhab.binding.asuswrt/src/main/resources/OH-INF/thing/router.xml

index 39dd664f304f40a89348c1cde0a556cdf5c7a22c..1b39fc9b2208a54a86c0a85349d02794947dbb36 100644 (file)
@@ -2,6 +2,11 @@
 
 This binding adds support to read information from ASUS-Routers (Copyright © ASUS).
 
+## Discovery
+
+The ASUS routers are discovered through UPnP in the local network.
+After adding a discovered router it is required to configure the username and password to use it.
+
 ## Supported Things
 
 This binding supports ASUS routers with Asuswrt or [Asuswrt-Merlin](https://www.asuswrt-merlin.net/) firmware.
index 73416289caf0246619cea1c91726b756787807e0..0ea6d2114455ef56e8a8813dbc851c71876339ff 100644 (file)
@@ -4,6 +4,7 @@
 
        <feature name="openhab-binding-asuswrt" description="Asuswrt Binding" version="${project.version}">
                <feature>openhab-runtime-base</feature>
+               <feature>openhab-transport-upnp</feature>
                <bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.asuswrt/${project.version}</bundle>
        </feature>
 </features>
diff --git a/bundles/org.openhab.binding.asuswrt/src/main/java/org/openhab/binding/asuswrt/internal/AsuswrtDiscoveryParticipant.java b/bundles/org.openhab.binding.asuswrt/src/main/java/org/openhab/binding/asuswrt/internal/AsuswrtDiscoveryParticipant.java
new file mode 100644 (file)
index 0000000..1705023
--- /dev/null
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2010-2023 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.asuswrt.internal;
+
+import static org.openhab.binding.asuswrt.internal.constants.AsuswrtBindingConstants.PROPERTY_HOSTNAME;
+import static org.openhab.binding.asuswrt.internal.constants.AsuswrtBindingConstants.THING_TYPE_ROUTER;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.jupnp.model.meta.DeviceDetails;
+import org.jupnp.model.meta.RemoteDevice;
+import org.openhab.core.config.discovery.DiscoveryResult;
+import org.openhab.core.config.discovery.DiscoveryResultBuilder;
+import org.openhab.core.config.discovery.upnp.UpnpDiscoveryParticipant;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.thing.ThingUID;
+import org.osgi.service.component.annotations.Component;
+
+/**
+ * The {@link AsuswrtDiscoveryParticipant} discovers the ASUS routers using UPnP.
+ *
+ * @author Wouter Born - Initial contribution
+ */
+@NonNullByDefault
+@Component(service = UpnpDiscoveryParticipant.class, configurationPid = "discovery.asuswrt")
+public class AsuswrtDiscoveryParticipant implements UpnpDiscoveryParticipant {
+    @Override
+    public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
+        return Set.of(THING_TYPE_ROUTER);
+    }
+
+    @Override
+    public @Nullable DiscoveryResult createResult(RemoteDevice device) {
+        ThingUID uid = getThingUID(device);
+        if (uid == null) {
+            return null;
+        }
+
+        DeviceDetails details = device.getDetails();
+
+        String host = details.getPresentationURI().getHost();
+        String model = details.getModelDetails().getModelNumber();
+
+        Map<String, Object> properties = new HashMap<>();
+        properties.put(PROPERTY_HOSTNAME, host);
+        properties.put(Thing.PROPERTY_VENDOR, details.getManufacturerDetails().getManufacturer());
+        properties.put(Thing.PROPERTY_MODEL_ID, model);
+        properties.put(Thing.PROPERTY_MAC_ADDRESS, details.getSerialNumber());
+
+        String label = String.format("ASUS %s Wireless Router (%s)", model, host);
+
+        return DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label)
+                .withRepresentationProperty(Thing.PROPERTY_MAC_ADDRESS).build();
+    }
+
+    @Override
+    public @Nullable ThingUID getThingUID(RemoteDevice device) {
+        DeviceDetails details = device.getDetails();
+        String modelName = details.getModelDetails().getModelName();
+        String modelManufacturer = details.getManufacturerDetails().getManufacturer();
+        if (modelManufacturer.toUpperCase().contains("ASUS") && ("ASUS Wireless Router".equalsIgnoreCase(modelName))) {
+            return new ThingUID(THING_TYPE_ROUTER, details.getSerialNumber().replace(':', '-'));
+        }
+        return null;
+    }
+}
index edcbdd2d0648aeb6949e28bf9929bb452dfc296b..46031a0ffd30b69dd90130aa0c8f4b819a10958f 100644 (file)
@@ -18,6 +18,7 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingTypeUID;
 
 /**
@@ -101,12 +102,14 @@ public class AsuswrtBindingConstants {
      * Properties
      */
 
+    // Router
+    public static final String PROPERTY_HOSTNAME = "hostname";
     // Interface
     public static final String PROPERTY_INTERFACE_NAME = "interfaceName";
     public static final String NETWORK_REPRESENTATION_PROPERTY = "interfaceName";
-    // client
+    // Client
     public static final String PROPERTY_CLIENT_NAME = "dnsName";
-    public static final String CLIENT_REPRESENTATION_PROPERTY = "macAddress";
+    public static final String CLIENT_REPRESENTATION_PROPERTY = Thing.PROPERTY_MAC_ADDRESS;
 
     /*
      * JSON request member names
index 691ab88bebc6671b0b732b4ee2ed2e9abd4a2c89..6c895d3bdc6d740754b5989691801020942c0749 100644 (file)
@@ -6,4 +6,21 @@
        <name>Asuswrt Binding</name>
        <description>Binding for ASUS routers (Asuswrt / Asuswrt-Merlin only)</description>
        <connection>local</connection>
+
+       <discovery-methods>
+               <discovery-method>
+                       <service-type>upnp</service-type>
+                       <match-properties>
+                               <match-property>
+                                       <name>manufacturer</name>
+                                       <regex>(?i).*ASUS.*</regex>
+                               </match-property>
+                               <match-property>
+                                       <name>modelName</name>
+                                       <regex>(?i)ASUS Wireless Router</regex>
+                               </match-property>
+                       </match-properties>
+               </discovery-method>
+       </discovery-methods>
+
 </addon:addon>
index 0d7a1d6424e6d3c34e47cb51dfcbcfa2ba0eb0f6..17eae93b9f5252d69231b4d37bc6eb9cedd5da35 100644 (file)
@@ -13,6 +13,8 @@
                        <channel-group id="client-list" typeId="client-list-group"></channel-group>
                </channel-groups>
 
+               <representation-property>macAddress</representation-property>
+
                <config-description>
                        <parameter name="hostname" type="text" required="true">
                                <context>network-address</context>