]> git.basschouten.com Git - openhab-addons.git/commitdiff
[ipcamera] Fix discovery crashes when networks have access rights issues in docker...
authorMatthew Skinner <matt@pcmus.com>
Sun, 2 Jul 2023 07:11:06 +0000 (17:11 +1000)
committerGitHub <noreply@github.com>
Sun, 2 Jul 2023 07:11:06 +0000 (09:11 +0200)
* Fix discovery crashes if network use is blocked by docker.
* Change log levels to be more useful.
* add better reolink discovery check

Signed-off-by: Matthew Skinner <matt@pcmus.com>
bundles/org.openhab.binding.ipcamera/README.md
bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/IpCameraDiscoveryService.java
bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifDiscovery.java

index 6bf837de986f597046f43cb04c32ed0b391aad56..225b55cf98bf1ace51667f25670e68c1a1f91e39 100644 (file)
@@ -133,10 +133,11 @@ Thing ipcamera:hikvision:West "West Camera"
 
 ## Discovery
 
-The discovery feature of openHAB can be used to find and setup any ONVIF cameras.
+The discovery feature of openHAB can be used to find and setup ONVIF cameras.
 This method should be preferred as it will discover the cameras IP, ports and URLs for you, making the setup much easier.
 The binding needs to use UDP port 3702 to discover the cameras with, so this port needs to be unblocked by your firewall or add the camera manually if the camera is not auto found.
 To use the discovery, just press the `+` icon located in the Inbox, then select the IpCamera binding from the list of installed bindings.
+The binding will only search using openHAB's currently selected primary network address, see <https://www.openhab.org/docs/settings/>.
 If your camera is not found after a few searches, it may not be ONVIF and in this case you will need to manually add the camera via the UI.
 Cameras that are not ONVIF should be added as a `generic` thing type and you will need to provide the URLs manually.
 
index 4992e02a9161f0a9b6a99624859249e8e7f3b0a3..a51c4fcf42c8401869ba5269f3e723e2e8dc4dd5 100644 (file)
@@ -22,9 +22,12 @@ import org.openhab.core.config.discovery.AbstractDiscoveryService;
 import org.openhab.core.config.discovery.DiscoveryResult;
 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
 import org.openhab.core.config.discovery.DiscoveryService;
+import org.openhab.core.net.NetworkAddressService;
 import org.openhab.core.thing.ThingTypeUID;
 import org.openhab.core.thing.ThingUID;
+import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -39,9 +42,12 @@ import org.slf4j.LoggerFactory;
 public class IpCameraDiscoveryService extends AbstractDiscoveryService {
 
     private final Logger logger = LoggerFactory.getLogger(IpCameraDiscoveryService.class);
+    private final NetworkAddressService networkAddressService;
 
-    public IpCameraDiscoveryService() {
+    @Activate
+    public IpCameraDiscoveryService(@Reference NetworkAddressService networkAddressService) {
         super(SUPPORTED_THING_TYPES, 0, false);
+        this.networkAddressService = networkAddressService;
     }
 
     @Override
@@ -65,7 +71,7 @@ public class IpCameraDiscoveryService extends AbstractDiscoveryService {
     @Override
     protected void startScan() {
         removeOlderResults(getTimestampOfLastScan());
-        OnvifDiscovery onvifDiscovery = new OnvifDiscovery(this);
+        OnvifDiscovery onvifDiscovery = new OnvifDiscovery(networkAddressService, this);
         try {
             onvifDiscovery.discoverCameras();
         } catch (UnknownHostException | InterruptedException e) {
index b8e70461a18ac2de8df8c58de22d777eb60c2236..dc49bf3bd5e98fde7fc95d17b13ab80478fa74d3 100644 (file)
@@ -35,6 +35,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.ipcamera.internal.Helper;
 import org.openhab.binding.ipcamera.internal.IpCameraDiscoveryService;
+import org.openhab.core.net.NetworkAddressService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -62,16 +63,21 @@ import io.netty.util.concurrent.GlobalEventExecutor;
  */
 
 @NonNullByDefault
+@io.netty.channel.ChannelHandler.Sharable
 public class OnvifDiscovery {
     private IpCameraDiscoveryService ipCameraDiscoveryService;
     private final Logger logger = LoggerFactory.getLogger(OnvifDiscovery.class);
+    private final NetworkAddressService networkAddressService;
     public ArrayList<DatagramPacket> listOfReplys = new ArrayList<DatagramPacket>(10);
 
-    public OnvifDiscovery(IpCameraDiscoveryService ipCameraDiscoveryService) {
+    public OnvifDiscovery(NetworkAddressService networkAddressService,
+            IpCameraDiscoveryService ipCameraDiscoveryService) {
         this.ipCameraDiscoveryService = ipCameraDiscoveryService;
+        this.networkAddressService = networkAddressService;
     }
 
     public @Nullable List<NetworkInterface> getLocalNICs() {
+        String primaryHostAddress = networkAddressService.getPrimaryIpv4HostAddress();
         List<NetworkInterface> results = new ArrayList<>(2);
         try {
             for (Enumeration<NetworkInterface> enumNetworks = NetworkInterface.getNetworkInterfaces(); enumNetworks
@@ -82,7 +88,15 @@ public class OnvifDiscovery {
                     InetAddress inetAddress = enumIpAddr.nextElement();
                     if (!inetAddress.isLoopbackAddress() && inetAddress.getHostAddress().toString().length() < 18
                             && inetAddress.isSiteLocalAddress()) {
-                        results.add(networkInterface);
+                        if (inetAddress.getHostAddress().equals(primaryHostAddress)) {
+                            results.add(networkInterface);
+                            logger.debug("Scanning network {} for any ONVIF cameras", primaryHostAddress);
+                        } else {
+                            logger.debug("Skipping network {} as it was not selected as openHAB's 'Primary Address'",
+                                    inetAddress.getHostAddress());
+                        }
+                    } else {
+                        logger.debug("Skipping network {} as it was not site local", inetAddress.getHostAddress());
                     }
                 }
             }
@@ -130,8 +144,18 @@ public class OnvifDiscovery {
             if (!xAddr.isEmpty()) {
                 searchReply(xAddr, xml);
             } else if (xml.contains("onvif")) {
-                logger.info("Possible ONVIF camera found at:{}", packet.sender().getHostString());
-                ipCameraDiscoveryService.newCameraFound("onvif", packet.sender().getHostString(), 80);
+                String brand;
+                try {
+                    brand = getBrandFromLoginPage(packet.sender().getHostString());
+                } catch (IOException e) {
+                    brand = "onvif";
+                }
+                logger.info("Possible {} camera found at:{}", brand, packet.sender().getHostString());
+                if ("reolink".equals(brand)) {
+                    ipCameraDiscoveryService.newCameraFound(brand, packet.sender().getHostString(), 8000);
+                } else {
+                    ipCameraDiscoveryService.newCameraFound(brand, packet.sender().getHostString(), 80);
+                }
             }
         }
     }
@@ -141,20 +165,20 @@ public class OnvifDiscovery {
             return "dahua";
         } else if (response.toLowerCase().contains("dahua")) {
             return "dahua";
+        } else if (response.toLowerCase().contains("doorbird")) {
+            return "doorbird";
         } else if (response.toLowerCase().contains("foscam")) {
             return "foscam";
         } else if (response.toLowerCase().contains("hikvision")) {
             return "hikvision";
         } else if (response.toLowerCase().contains("instar")) {
             return "instar";
-        } else if (response.toLowerCase().contains("doorbird")) {
-            return "doorbird";
+        } else if (response.toLowerCase().contains("reolink")) {
+            return "reolink";
         } else if (response.toLowerCase().contains("ipc-")) {
             return "dahua";
         } else if (response.toLowerCase().contains("dh-sd")) {
             return "dahua";
-        } else if (response.toLowerCase().contains("reolink")) {
-            return "reolink";
         }
         return "onvif";
     }
@@ -197,6 +221,8 @@ public class OnvifDiscovery {
     public void discoverCameras() throws UnknownHostException, InterruptedException {
         List<NetworkInterface> nics = getLocalNICs();
         if (nics == null || nics.isEmpty()) {
+            logger.warn(
+                    "No 'Primary Address' selected to use for camera discovery. Check openHAB's Network Settings page to select a valid Primary Address.");
             return;
         }
         NetworkInterface networkInterface = nics.get(0);