Skip to content

Auto Discovery

There are two methods that the device service can use to discover and add ONVIF compliant cameras using WS-Discovery: multicast and netscan.

For more info on how WS-Discovery works, see here.

How To


Ensure that the cameras are all installed and configured before attempting discovery.

Device discovery is triggered by the device SDK. Once the device service starts, it will discover the Onvif camera(s) at the specified interval.


You can also manually trigger discovery using this command: curl -X POST http://<service-host>:59984/api/v3/discovery

Step 1. Discovery Configuration

See Configuration Section for full details


Alternatively, for netscan you can set the DiscoverySubnets automatically after the service has been deployed by running the bin/ script

  1. For Netscan, there is a one line command to determine the DiscoverySubnets of your current machine:
        ip -4 -o route list scope link | sed -En "s/ dev ($(find /sys/class/net -mindepth 1 -maxdepth 2 -not -lname '*devices/virtual*' -execdir grep -q 'up' "{}/operstate" \; -printf '%f\n' | paste -sd\| -)).+//p" | grep -v "" | sort -u | paste -sd, -
    Example Output:

Define the following configurations in cmd/res/configuration.yaml for auto-discovery mechanism:

# The location of Provision Watcher yaml files to import when using auto-discovery
ProvisionWatchersDir: ./res/provisionwatchers
    Enabled: true
    Interval: 1h

# Custom configs
DefaultSecretName: credentials001
# Select which discovery mechanism(s) to use
DiscoveryMode: both # netscan, multicast, or both
# The target ethernet interface for multicast discovering
DiscoveryEthernetInterface: eth0
# List of IPv4 subnets to perform netscan discovery on, in CIDR format (X.X.X.X/Y)
# separated by commas ex: ","
DiscoverySubnets: "" # Fill in with your actual subnet(s)

Define the following environment variables in docker-compose.yaml:

    DEVICE_DISCOVERY_ENABLED: "true"  # enable device discovery
    DEVICE_DISCOVERY_INTERVAL: "1h"   # set to desired interval

    # The target ethernet interface for multicast discovering
    # The Secret Name of the default credentials to use for devices
    # Select which discovery mechanism(s) to use
    APPCUSTOM_DISCOVERYMODE: "both" # netscan, multicast, or both
    # List of IPv4 subnets to perform netscan discovery on, in CIDR format (X.X.X.X/Y)
    # separated by commas ex: ","
    APPCUSTOM_DISCOVERYSUBNETS: "" # Fill in with your actual subnet(s)

Enter the subnet into this command, and execute it to set the DiscoverySubnets


If you are operating in secure mode, you must use the Consul ACL Token generated previously. If not, you can omit the -H "X-Consul-Token:<consul-token>" portion of the command.

curl --data '<subnet>' -H "X-Consul-Token:<consul-token>" -X PUT "http://localhost:8500/v1/kv/edgex/v3/device-onvif-camera/AppCustom/DiscoverySubnets"

Step 2. Set CredentialsMap

See Credentials Guide for more information.

Configuration Guide



For docker, set the env var APPCUSTOM_DISCOVERYMODE

DiscoveryMode allows you to select which discovery mechanism(s) to use. The three options are: netscan, multicast, and both.


netscan works by sending unicast UDP WS-Discovery probes to a set of IP addresses on the CIDR subnet(s) configured via DiscoverySubnets.

For example, if the provided CIDR is, it will probe the all IP addresses from to This will result in a total of 254 probes on the network.

This method is a little slower and more network-intensive than multicast WS-Discovery, because it has to make individual connections. However, it can reach a much wider set of networks and works better behind NATs (such as docker networks).


multicast works by sending a single multicast UDP WS-Discovery Probe to the multicast address on port 3702. In certain networks this traffic is blocked, and it is also not forwarded across subnets, so it is not compatible with NATs such as docker networks (except in the case of running an Onvif simulator inside the same docker network).

multicast requires some additional configuration. Edit the add-device-onvif-camera.yml in the edgex-compose/compose-builder as follows:


        image: edgexfoundry/device-onvif-camera${ARCH}:0.0.0-dev
        container_name: edgex-device-onvif-camera
        hostname: edgex-device-onvif-camera
        read_only: true
        restart: always
        network_mode: "host"
            SERVICE_HOST: # set to internal ip of your machine
            MESSAGEQUEUE_HOST: localhost
            EDGEX_SECURITY_SECRET_STORE: "false"
            REGISTRY_HOST: localhost
            CLIENTS_CORE_DATA_HOST: localhost
            CLIENTS_CORE_METADATA_HOST: localhost
            # Host Network Interface, IP, Subnet
            APPCUSTOM_DISCOVERYETHERNETINTERFACE: wlp1s0 # determine this setting for your machine
            APPCUSTOM_DISCOVERYSUBNETS: # determine this setting for your machine
            APPCUSTOM_DISCOVERYMODE: multicast
        - consul
        - data
        - metadata
        - no-new-privileges:true
        user: "${EDGEX_USER}:${EDGEX_GROUP}"
        command: --cp=consul.http://localhost:8500


This option combines both netscan and multicast.



For docker, set the env var APPCUSTOM_DISCOVERYSUBNETS

This is the list of IPv4 subnets to perform netscan discovery on, in CIDR format (X.X.X.X/Y) separated by commas ex: ",". See how to configure this value here.

Also, the following one-line command can determine the subnets of your machine:

ip -4 -o route list scope link | sed -En "s/ dev ($(find /sys/class/net -mindepth 1 -maxdepth 2 -not -lname '*devices/virtual*' -execdir grep -q 'up' "{}/operstate" \; -printf '%f\n' | paste -sd\| -)).+//p" | grep -v "" | sort -u | paste -sd, -
Example Output:




This is the target Ethernet Interface to use for multicast discovering. Keep in mind this interface is relative to the environment it is being run under. For example, when running in docker, those interfaces are different from your host machine's interfaces.



For docker, set the env var APPCUSTOM_PROBEASYNCLIMIT

This is the maximum simultaneous network probes when running netscan discovery.



For docker, set the env var APPCUSTOM_PROBETIMEOUTMILLIS

This is the maximum amount of milliseconds to wait for each IP probe before timing out. This will also be the minimum time the discovery process can take.




This is the maximum amount of seconds the discovery process is allowed to run before it will be cancelled. It is especially important to have this configured in the case of larger subnets such as /16 and /8.

Adding the Devices to EdgeX

sequenceDiagram Onvif Device Service->>Onvif Camera: WS-Discovery Probe Onvif Camera->>Onvif Device Service: Probe Response Onvif Device Service->>Onvif Camera: GetDeviceInformation Onvif Camera->>Onvif Device Service: GetDeviceInformation Response Onvif Device Service->>Onvif Camera: GetNetworkInterfaces Onvif Camera->>Onvif Device Service: GetNetworkInterfaces Response Onvif Device Service->>EdgeX Core-Metadata: Create Device EdgeX Core-Metadata->>Onvif Device Service: Device Added


The device service is able to rediscover and update devices that have been discovered previously. Nothing additional is needed to enable this. It will run whenever the discover call is sent, regardless of whether it is a manual or automated call to discover.

The following logic is to determine if the device is already registered or not.

%% Note: The node and edge definitions are split up to make it easier to adjust the %% links between the various nodes. flowchart TD %% -------- Node Definitions -------- %% Multicast[/Devices Discovered
via Multicast/] Netscan[/Devices Discovered
via Netscan/] DupeFilter[Filter Duplicate Devices
based on EndpointRef] MACMatches{MAC Address
matches existing
device?} RefMatches{EndpointRef
matches existing
device?} IPChanged{IP Address
Changed?} MACChanged{MAC Address
Changed?} UpdateIP[Update IP Address] UpdateMAC(Update MAC Address) RegisterDevice(Register New Device
With EdgeX) DeviceNotRegistered(Device Not Registered) PWMatches{Device matches
Provision Watcher?} %% -------- Graph Definitions -------- %% Multicast --> DupeFilter Netscan --> DupeFilter DupeFilter --> ForEachDevice subgraph ForEachDevice[For Each Unique Device] MACMatches -->|Yes| IPChanged MACMatches -->|No| RefMatches RefMatches -->|Yes| IPChanged RefMatches -->|No| ForEachPW ForEachPW --> PWMatches PWMatches-->|No Matches| DeviceNotRegistered IPChanged -->|No| MACChanged IPChanged -->|Yes| UpdateIP UpdateIP --> MACChanged MACChanged -->|Yes| UpdateMAC PWMatches -->|Yes| RegisterDevice end


netscan discovery was called, but DiscoverySubnets are empty!

This message occurs when you have not configured the AppCustom.DiscoverySubnets configuration. It is required in order to know which subnets to scan for Onvif Cameras. See here

route ip+net: no such network interface

This message occurs when you have multicast discovery enabled, but AppCustom.DiscoveryEthernetInterface is configured to a network interface that does not exist. See here