# The Devices tab One row per device this bench runs, and below it the selected device: its buttons and five panes. ## The Devices card ![The Devices card](../imgs/gui/devices-card.png){width="100%"} | Column | Shows | |---|---| | **Fleet** | Which of this bench's fleets declares the device, and a check box. Checked devices are the **working fleet**: the ones **Fleet up** ![Fleet up](../imgs/gui/btn-fleet-up.png){height=22px} starts and a headless bench keeps running. Ticking it saves `autostart` in that fleet's file. *View ▸ Fleet* chooses which fleets the table shows. | | **Name** | The device's name on this bench. It also names its log and its folder. | | **Host** | *this bench*, or the name of the other bench it runs on — see [Several benches](../usage/remote.md#driving-other-benches-from-this-console). | | **Source** | What it runs: `package==version` for a release, or the repository and ref for a checkout. | | **State** | `stopped`, `starting`, `running` (answering on its port) or `exited` (it died — the Log says why). | | **Port** | The TCP port experiments connect to. | | **PID**, **Started** | The server process, and when it started. | Double-click a row to open [Device config](#edit-device-config). Right-click for the same actions as the *Device* menu. The buttons in the card's header act on the whole bench: | Button | Icon | Does | |---|---|---| | **Declare** | ![Declare](../imgs/gui/btn-fleet-declare.png){width=39px} | Add a device to the fleet — see [below](#declare-device). | | **Fleet up** | ![Fleet up](../imgs/gui/btn-fleet-up.png){width=39px} | Install what is missing and start every checked device. | | **Fleet down** | ![Fleet down](../imgs/gui/btn-fleet-down.png){width=39px} | Stop every server running here, checked or not. | | **Control** | ![Control](../imgs/gui/btn-fleet-control.png){width=39px} | Open the Control window with a panel for every running device — see [below](#control-the-control-window). | | **Refresh** | ![Refresh](../imgs/gui/btn-fleet-refresh.png){width=39px} | Re-read the bench now (F5). | ### Declare device **Declare** ![Declare](../imgs/gui/btn-fleet-declare.png){height=22px}, or *Device ▸ Add device…* (Ctrl+N), opens **Declare device**: a new device in the fleet file. On a bench with no module installed yet it first offers to open [the Hub](menus.md#hub). ```{image} ../imgs/gui/dialog-declare.png :width: 340px :alt: The Declare device dialog ``` | Field | Means | |---|---| | **Name** | The device's name on this bench — proposed from the package. It names its log and folder, so it must be unique across all the bench's fleets. | | **Package** | Which installed module runs it. Only installed modules are listed, and of those only device modules and modules whose kind is not known yet. | | **Project** | Where the module lives, its latest release and vendor — for reference. | | **Source — one of** | **Release (PyPI)** with a version (empty = the newest), *or* **Repository (git)** with a repository and a **ref** (branch, tag or commit). The drop-downs list every release on PyPI and every release tag of the repository, newest first. Pick a repository when you want [field tests](../usage/field_test.md) — a release does not carry them. | | **Args** | Passed to the device server — usually how it finds the instrument, such as `--address`. A port is chosen for you unless you add `--tcp-port`. | | **Env** | `KEY=VALUE` lines for the server. They win over the device's `.env`. | | **part of the working fleet** | Ticked: **Fleet up** ![Fleet up](../imgs/gui/btn-fleet-up.png){height=22px} starts it. | **OK** writes the device into the fleet file that is open — on a new bench, `/fleets/default.yaml`. ### Control — the Control window **Control** ![Control](../imgs/gui/btn-fleet-control.png){height=22px} on this card, or *View ▸ Control window*, opens a window with a panel for **every running device** — driving instruments by hand: read their values, set them, press their operations. **Control** ![Control](../imgs/gui/btn-device-control.png){height=22px} on a device's own card, or *Device ▸ Control…* (Ctrl+D), opens that device alone, in a window of its own. ```{image} ../imgs/gui/control-window.png :width: 760px :alt: The PLESTY Control window with the pm100d panel taken over and the k10cr1 panel still read-only ``` Each panel is built from what its device reports about itself — its parameters with their units, limits and choices, and its operations — so a power meter shows its wavelength and power range, a rotation stage its position and velocity, without anything written for either. Operations such as homing or a reset are left off. 1. Tick **Take control**. Until then the panel only reads: something may be measuring with that instrument right now, and the console would be a second client on it. ```{image} ../imgs/gui/take-control.gif :width: 760px :alt: Ticking Take control on the pm100d panel: its fields and operation buttons become usable. ``` 2. Change a value — the field will not go past what the instrument accepts — or press an operation's button. 3. **Refresh** reads every value once. The line at the top of each panel counts its controls and says whether it is read-only. Only a device whose server answers can be controlled; asking twice for one brings its panel forward rather than opening a second. A device that stops keeps its panel, marked as stopped. Panels dock, stack as tabs, or drag out onto a second screen; the **Panels** and **Layout** menus show, hide and reset them. The same panels open on another computer with [`plesty-bench control`](../cli/plesty-bench.md#control). ## The device card ![The card of the selected device](../imgs/gui/detail-card.png){width="100%"} The buttons act on the selected device. A button that cannot act right now is greyed out, and hovering over it says why. | Button | Icon | Does | Available when | |---|---|---|---| | **Start** | ![Start](../imgs/gui/btn-device-start.png){width=39px} | Start the device server (Ctrl+R). Installs it first if needed, then waits until it answers. | it is not running | | **Stop** | ![Stop](../imgs/gui/btn-device-stop.png){width=39px} | Stop it (Ctrl+T): asks it to close the instrument first, then insists. | it is running, or exited | | **Restart** | ![Restart](../imgs/gui/btn-device-restart.png){width=39px} | Stop and start again. | it is installed | | **Control** | ![Control](../imgs/gui/btn-device-control.png){width=39px} | This device's panel, in a window of its own (Ctrl+D) — see [the Control window](#control-the-control-window). | the server answers | | **Edit** | ![Edit](../imgs/gui/btn-device-edit.png){width=39px} | Its declaration and `.env` (Ctrl+E) — see [below](#edit-device-config). | it is on this bench | | **Install** | ![Install](../imgs/gui/btn-device-install.png){width=39px} | Create its environment, as a job. | always | | **Update** | ![Update](../imgs/gui/btn-device-update.png){width=39px} | Pull a checkout and re-sync it, or reinstall a release, as a job. | it is installed | | **Field Test** | ![Field Test](../imgs/gui/btn-device-field_test.png){width=39px} | Run its field test (Ctrl+F) — see [below](#field-test). | it is installed from a repository that has a field test | | **Clear log** | ![Clear log](../imgs/gui/btn-device-clear_log.png){width=39px} | Empty its log — and with it the Traffic pane. | it is on this bench | | **Uninstall** | ![Uninstall](../imgs/gui/btn-device-uninstall.png){width=39px} | Stop it and remove its environment. | it is installed here | | **Remove** | ![Remove](../imgs/gui/btn-device-remove.png){width=39px} | Drop it from the fleet. Its environment stays. | it is on this bench | Starting a device — select its row, press *Start*, and watch the state go from `stopped` to `running` as the log fills: ```{image} ../imgs/gui/start-device.gif :width: 100% :alt: Selecting the stopped k10cr1 and pressing Start: its state turns to running and its log fills. ``` For a device on another bench, *Edit*, *Clear log*, *Uninstall* and *Remove* are done on that bench, and the five panes below are empty: each reads a file on the bench that runs the device. ### Edit — Device config **Edit** ![Edit](../imgs/gui/btn-device-edit.png){height=22px}, *Edit ▸ Device config…* (Ctrl+E), or a double-click on the device's row, opens **Device config**. Two tabs; **Save** writes both. ```{image} ../imgs/gui/dialog-device-config.png :width: 680px :alt: The Device config dialog on its Declaration tab ``` - **Declaration** — the same fields as [Declare device](#declare-device). Changing the **Name** renames the device: its `.env` and its log move with it. Stop it first. - **.env** — this device's own settings, one `KEY=VALUE` per line: an address, a serial number, a calibration constant. It stays on this bench and is read by the server and by its field tests. ```{image} ../imgs/gui/dialog-device-config-tab2.png :width: 680px :alt: The .env tab of the Device config dialog ``` ### Field Test **Field Test** ![Field Test](../imgs/gui/btn-device-field_test.png){height=22px}, or *Device ▸ Field Test…* (Ctrl+F), opens **Field test** for a device installed from a repository. **Run** starts the test as a job and follows it; the result lands in the Reports pane. The walkthrough is [Field-test a device](../usage/field_test.md). ```{image} ../imgs/gui/dialog-field-test.png :width: 335px :alt: The Field test dialog with tier, address, repetitions, options and gates ``` | Field | Means | |---|---| | **Tier** | **host** tests the module against the instrument: the device server is stopped for the run and started again afterwards. **client** tests through the running server, the way an experiment reaches it. | | **Address** | The instrument to test — `mock` runs the module's simulator and leaves the server alone. | | **Repetitions** | How often each measuring gate repeats; *script default* leaves it to the script. | | **carry on after a failed gate** | Run the remaining gates anyway. | | **host tier: leave a running server alone** | Do not stop the server — only sensible with `mock`. | | **Extra** | Further arguments for the module's own script. | | **Gates** | Which checks to run. All ticked is the full test. The line below lists what this module's script accepts. | ## The panes ### Log ![The Log pane](../imgs/gui/detail-log.png){width="100%"} The last 200 lines the device server printed. Each start writes a new log, which opens with a `=== plesty-server start …` line naming the exact command; **Clear log** ![Clear log](../imgs/gui/btn-device-clear_log.png){height=22px} starts another while the server runs. The earlier files stay in `logs/`. ### Jobs ![The Jobs pane](../imgs/gui/detail-jobs.png){width="100%"} This device's installs, updates, field tests and Terminal commands — *Job, State, Exit, Started*. Double-click one to follow its log in a window with a **Cancel job** button. ### Reports ![The Reports pane](../imgs/gui/detail-reports.png){width="100%"} The field-test reports published for this device — *Report, Outcome, Modified*. See [Field-test a device](../usage/field_test.md#reading-the-result). ### Terminal ![The Terminal pane](../imgs/gui/detail-terminal.png){width="100%"} Runs one command inside the environment that serves this device, so `python` and the module's own commands are that environment's. The line above the output names the environment and the working folder — the checkout for a repository install, the device's own folder for a release. Type a command and press **Run** (or Enter); **Stop** cancels it. It is not a shell: there is no pipe, redirection or wildcard. A checkout is installed without its development tools, so `plesty check` and `pytest` are not there; `python tests/field_test.py --help` is. ### Traffic ![The Traffic pane](../imgs/gui/detail-traffic.png){width="100%"} Each request the server handled — *When, Request, Target, ms, Outcome*. It records what was asked, not the data returned, and a failure shows its error type. *answer lost* marks a reply the client never received: it timed out and reconnected, while the device did the work anyway. The history reaches back as far as the log does.