# Discovery

> Letting a driver scan for devices or points, what each scan needs and returns, the progress and cancel behavior, adding results, and pairing a Matter device over Bluetooth.

For drivers whose protocol supports a real scan, **Discover** finds devices or points for you instead of having you type them. It lives on a driver node's command bar (and, for Modbus RTU, in the Discover units card of a serial line's page), while everything the scan takes lives in the driver page's Scan scope card: the bar carries the command, the card carries its scope. All of it needs Configure connector: a role without the bit is not drawn the scope card or the button. A scan refuses while a run holds the station or the runtime is stopped. When a scan returns nothing, that is a scan result, not a missing feature: the button appears only where a scan can produce results.

## Which drivers scan {#which-drivers-scan}

| Driver | What the scan does | Needs |
| --- | --- | --- |
| Simulated | Lists its catalog of simulated device models, one ready-to-use instance each, with their channels. | Nothing. |
| Modbus TCP | Sends Read Device Identification (function 43/14) to explicit hosts and unit ids; a validated Modbus exception proves a unit without naming it. Returns the endpoint and no tags. | The Scan scope card. |
| Modbus RTU | Probes an inclusive unit-id range sequentially over a line's saved tuple, with the same request and no register access. | A line, disabled or without enabled devices, and a unit-id range. |
| OPC UA | Queries one server for its advertised endpoints, then browses each endpoint's address space for points. | The server address, in the driver page's Scan scope card ("OPC UA server address, e.g. opc.tcp://plc-host:4840"). Without it, or with an address that is not one, Discover greys and says what is expected. |
| Rockwell EtherNet/IP | Broadcasts ListIdentity and browses each controller's tags. | Nothing. |
| BACnet | Broadcasts Who-Is and listens for I-Am answers, each device appearing the moment it replies. Returns the address, port and device instance, and no tags. | Nothing. |
| Redfish | Reads the service address it is given and walks its first system, manager and chassis. Returns the service and its points. | The Scan scope card. |
| AVEVA PI | Walks the AF element it is given and everything under it. Returns the service and one point per attribute. | The Scan scope card. |
| OCPP | Lists the charge points currently connected to this station. | Nothing. |
| Matter | Lists the nodes already commissioned into this station's Fabric. | Nothing. |

Siemens S7, Beckhoff ADS, Mitsubishi MC, IEC 61850, LoRaWAN and HTTP have no scan and show no button. The button appears only once the embedded server is running, because it is the server's driver registry that answers whether a scan can run, and it appears only for the drivers this version installs: if the registry answers with an assembly the application does not recognize, the button stays away and the Events page records that the installed driver is not the one this version ships.

## Modbus TCP: the Scan scope card {#modbus-tcp-the-scan-scope-card}

The card appears on the Modbus TCP driver's page: "Read-only device identification; registers are configured after Add."

| Field | Values / default | Effect |
| --- | --- | --- |
| **IPv4 host or CIDR** | One address, or a CIDR from /24 to /32; the app never infers the local subnet. | Every host address of the range, the network and broadcast addresses excluded. |
| **Port** | 1 to 65535; 502. | The port every host is dialed on. |
| **Unit IDs** | Values, comma-separated lists or ascending ranges, 0 to 255 ("1, 3, 8-16"); "1". | Each host is asked for each id. |
| **Minimum transaction interval (ms)** | 0 to 1000; 0. | Silence between completed probes on the same host; hosts are paced independently. Scan-local: it is not written into the devices you add. |

The line under the fields is the budget: "2 hosts × 3 unit IDs = 6 probes · limit 256", with "· 100 ms silence per host." when set. A scan may send at most 256 probes; over the budget the line turns red ("This scan would send 512 probes; reduce the network or unit-id range to 256 or fewer.") and Discover greys. Bad input is named the same way ("'10.0.0' is not a valid four-octet IPv4 address.", "The CIDR prefix must be between /24 and /32.", "Enter at least one unit id (0-255).", "Unit-id range '9-3' must be ascending."). Changing any scope field discards the results of the previous scan, because they described a different scope. At most four hosts are scanned at once, one connection per host.

## Modbus RTU {#modbus-rtu}

The scan is on the line's page, not the driver's: **Unit ID start** and **Unit ID end** (1 to 247, ascending, 1 to 32 by default) and their own Discover button, with an estimate of the worst case ("32 probes · up to ~32.1 s, including 4.011 ms silence before each probe."). The scan opens the port once with the line's saved settings, probes each unit in turn, and refuses an active line rather than interrupting it: "This line is in use. Disable it before discovery; Ganter Lab will not interrupt or re-enable the bus automatically." A pending edit on the line is saved before the scan starts; if it cannot be, the scan does not start ("Discovery was not started because the serial-line edit could not be saved."). The [Serial lines](connector-lines) page covers the rest of that card.

## Redfish and AVEVA PI: the service the scan reads {#redfish-and-aveva-pi-the-service-the-scan-reads}

Neither a Redfish service nor a PI System announces itself on a network this station can listen to, so those two scans read the one service you point them at, in the driver page's Scan scope card. Redfish takes the service address (`https://bmc-host`, or `https://bmc-host:8443` where it answers elsewhere) and always reads it over HTTPS, because the device's credentials ride on every request; an address that asks for the clear transport is refused where it is typed. AVEVA PI takes the service address and, after a `#`, the AF element the walk starts from: `https://pi-host/piwebapi#\\AF-SRV\Plant\Line 3`. Without that element there is nothing to walk, so Discover greys and says what is expected.

Both scans read the service without credentials, because they run before the device that would hold them exists. A service that authenticates every request therefore answers nothing and the scan finds nothing: add that service by hand, and its points with it.

## Running a scan {#running-a-scan}

While the scan runs the driver's page prints a status line and the bar's Discover turns into **Cancel**. The status comes from two independent stages, endpoint discovery and channel browsing: "Scanning endpoints…", "Inspecting endpoint 2…", "Reading channels from opc.tcp://plc:4840…", then "Found 3 device(s)."; the drivers that report their own progress say "Querying OPC UA server … for advertised endpoints…" and "Found 2 endpoints.", "Searching for Rockwell controllers…", "Scanning BACnet devices…", "Inspecting commissioned Matter node 1 of 2…", "Scanning 2 hosts × 3 unit IDs…" or "Probing unit 5 (5 of 32)…". A scan that stops on a driver error keeps what it found and says so: "The scan stopped with an error after finding 1 device(s). The list may be incomplete." An endpoint whose channels could not be read is still listed, with zero tags.

The scan owns the driver while it runs: you cannot select another node ("Cancel discovery before leaving this driver."), add a device or a line, enable or disable lines, or use row actions until it ends. Results belong to the window that started the scan: another browser tab on the same station does not see them.

### Cancelling {#cancelling}

**Cancel** ("Canceling…" once pressed) stops both stages. Candidates fully prepared before the cancel stay listed; the endpoint whose channels were still being read is discarded. The status reads "Discovery canceled." and the feed "Discovery canceled for OPC UA; 2 completed result(s) retained." The scan stays occupied until the driver's temporary socket, client or session has closed; after two seconds the status says "Waiting for the driver to release its discovery resources…" rather than pretending the scan already stopped, because a driver does not always let go the instant it is asked to.

## The results {#the-results}

The **Discovered devices** card (on a line, **Discovered units**) lists one card per candidate: an editable **name**, the **endpoint**, and "2 of 5 tags selected". Under it a compact grid of the candidate tags with an **Add** tick (on by default), **Tag**, **Type** and **Access**; with none, "No tags reported. Add the device to configure tags in its editor." Nothing is persisted until you press **Add device** on a card ("Adding…" while it runs): the device is created under a name unique on the driver with exactly the ticked tags, the card leaves the list, the page opens on the new device, and the feed reads "Added 'Pump' with 3 tag(s)." Discovered tags arrive read-only or writable as the driver reported them, with their type, and with the default pipeline; nothing else is inferred.

A candidate that matches a device you already have is marked **Already configured** and offers **Open** instead of Add, so a scan never creates an accidental duplicate. Only stable identities are matched: a Modbus RTU unit on the same line, and a Matter node id. Other drivers match nothing, because a reachable endpoint is not proof that it is the same equipment.

**Dismiss** clears the list, and waits for the scan: while one is running it is greyed, because
clearing the list mid-scan also cancels it and throws away everything that had already answered.
Selecting another driver, or changing the scope, clears it too. While a scan runs, deleting a
device or a tag and moving a device into a folder grey with the same reason: the scan holds the
driver, and the command would have failed after you confirmed it. On Modbus RTU the unit id is a column of its own, and an id already configured on the line is refused when added: "Unit 5 is already configured on 'Line 1'."

## Pairing a Matter device {#pairing-a-matter-device}

Matter commissions the physical device over Bluetooth before it exists here, so the Matter driver's first verb is **Pair device**, not Add device, and it opens a form on the driver's page (the New… menu and the driver's right-click menu offer the same). Pairing needs Configure connector, a usable Bluetooth LE radio on this computer, and an existing Thread network whose dataset you are allowed to obtain. The form says so: "Put the physical device in pairing mode before continuing. Pairing uses Bluetooth on this computer."

| Field | What it is |
| --- | --- |
| **Device name** | The editable name the device will have in the Connector; "Matter device" by default, with "Kitchen light" as the placeholder. |
| **Matter setup code** | The official 11- or 21-digit manual code printed on the device, or the complete QR payload beginning with `MT:`. Hidden as typed; **Show setup code** reveals it. |
| **Thread Operational Dataset** | The complete active dataset of the Thread network, in hexadecimal, from the network administrator or the Border Router; "Ganter Lab cannot invent credentials for an existing network." Hidden as typed; **Show dataset** reveals it. |

**Pair device** is enabled once all three are filled and the station accepts mutations. The form then walks five steps, **Validate**, **Find**, **Pair**, **Join Thread** and **Save**, with a status line under them: "Validating the setup code and Thread dataset…", "Searching for the device over Bluetooth…", "Authenticating and pairing the device…", "Sending the existing Thread network configuration…", "Waiting for the device to join the Thread network…", "Saving the commissioned node in the local Fabric…", "Pairing complete." **Cancel** is accepted only until the matching advertisement is selected ("Stop before the device is changed"); from then on the button reads "Finishing safely…", because the device has been changed and the station must record the node even if you leave. **Close** dismisses the form while nothing runs.

On success the device is created with only the node id as its identity (the setup code and dataset are never stored, logged or shown again), the page opens on it, and the feed reads "Paired Matter device 'Kitchen light'." If the node was commissioned but its device could not be created, the feed says so and Discover is the recovery path. Failures are said plainly and the form stays open for a retry: an invalid code or dataset, no usable Bluetooth adapter, Bluetooth denied or turned off, no matching device ("Put it in pairing mode, keep it nearby and try again."), a rejected setup code, a device that did not join the Thread network (its node stays in the Fabric and can be recovered with Discover), a Fabric that could not be saved (when the device was already commissioned: "Do not reset the device until the Fabric storage problem is resolved."), or another pairing already running. One pairing runs at a time; while it runs you cannot leave the driver ("Wait for Matter pairing to finish before leaving this driver.").

## What discovery does not do {#what-discovery-does-not-do}

A scan never persists anything by itself, never changes an existing device, and never re-runs on its own. It does not infer subnets, register maps or serial settings, does not enable or disable a line, and does not remove dismissed candidates from the equipment. It is refused for a driver the package does not carry. What each driver's results contain is on that driver's page under [Drivers](drivers).
