diff --git a/README.md b/README.md index db88bcd..a386458 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ NVCurve brings MSI Afterburner-style per-point voltage-frequency curve control t > **Blackwell GPU memory** — This is a specialized fork with extended memory offset support (up to +3000 MHz) for Blackwell GPUs (RTX 50-series). \ > **Fan Controls** — There is an additional "Fans" tab to setup a customized fan curve, controlling all fans or individual fans. \ > **Dashboard** — The default tab is an Dashboard with additional information (PCIe link speed, VBIOS information, Max Core Clock, Throttle Reason and much much more.) \ -> **WireView Pro II** — Native monitoring of the Thermal Grizzly WireView Pro II 12VHPWR connector: the device is auto-detected over USB and a dedicated tab shows live temperature, power and current readings — no external exporter or kernel module required. The tab only appears while the device is connected.\ +> **WireView Pro II** — Native monitoring of the Thermal Grizzly WireView Pro II 12VHPWR connector: a dedicated tab shows live temperature, power and current readings — no external exporter or kernel module required. The host needs a one-time setup (udev rule + port access, see [WireView Pro II Setup](docs/WireView.md)); after that the device is auto-detected over USB and the tab only appears while it is connected. \ > **Authentification** — For production deplyoment, I added authentification with bcrypt hashing to allow only one or multiple people to have access. \ > Installing the pre-built PyPI package will NOT include these features. You must build from source. @@ -206,6 +206,7 @@ The GPU key can be a UUID, `pci:XXXX`, or `idx:N` fallback. Find your GPU key wi - **[Installation](docs/Installation.md)** — Prerequisites, source build, troubleshooting - **[Usage Guide](docs/Usage-Guide.md)** — Web UI, CLI reference, systemd service - **[Tips and Tricks](docs/Tips-and-Tricks.md)** — Workflows, curve flattening, safety +- **[WireView Pro II Setup](docs/WireView.md)** — One-time host setup (udev rule + port access) for the 12VHPWR connector monitor ## Upgrading diff --git a/docs/WireView.md b/docs/WireView.md new file mode 100644 index 0000000..a3b1636 --- /dev/null +++ b/docs/WireView.md @@ -0,0 +1,112 @@ +# WireView Pro II Setup + +NVCurve reads the [Thermal Grizzly WireView Pro II](https://www.thermal-grizzly.com/en/wireview-pro-ii-gpu/s-tg-wv-p2) (12 VHPWR connector monitor) directly over its USB CDC/ACM serial port — **no exporter, no GUI, no kernel module required**. + +Before the first use, the host needs a one-time setup: a udev rule so the serial port is accessible under a stable name and left alone by other tools. After that, NVCurve auto-detects the device over USB — the WireView tab appears while the device is connected and disappears when it is unplugged. + +## Why a one-time setup is needed + +The WireView is an STM32 CDC/ACM virtual serial port (VID `0483`, PID `5740`). Out of the box, Linux: + +- creates the port as `root:uucp 0660` with no stable device name, and +- lets **ModemManager** probe every new CDC-ACM port with AT/QCDM commands for up to ~30 s after each plug — it holds the port open and sends bytes the device does not expect. + +The udev rule below fixes both: the node becomes `root:dialout 0660`, a stable `/dev/wireview-pro2` symlink is created, and ModemManager is told to ignore the device. + +## 1. Install the udev rule + +```sh +sudo tee /etc/udev/rules.d/99-wireview.rules > /dev/null <<'EOF' +# WireView Pro II udev rules +# +# Same access policy as wireview-hwmon's 99-wireview-hwmon.rules: the node is +# 0660 root:dialout, and the user logged in at the local seat gets an ACL via +# uaccess. systemd applies that tag on hotplug from 73-seat-late.rules, which +# runs before this 99- file and so never sees it, so each rule also runs the +# uaccess builtin itself. The tag is still needed: logind uses it to move the +# ACL to the new active session on a user switch. + +ACTION=="remove", GOTO="wireview_end" + +# Normal operation (STM32 CDC/ACM virtual serial port) +SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", GROUP="dialout", MODE="0660", TAG+="uaccess", RUN{builtin}+="uaccess", SYMLINK+="wireview-pro2" + +# Keep ModemManager away: it probes every new CDC-ACM port with AT and QCDM +# commands for about half a minute, holding the port and sending the device +# bytes it does not expect. +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="0483", ATTR{idProduct}=="5740", ENV{ID_MM_DEVICE_IGNORE}="1" +SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{ID_MM_PORT_IGNORE}="1" + +# DFU bootloader mode (firmware update) +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="0483", ATTR{idProduct}=="df11", GROUP="dialout", MODE="0660", TAG+="uaccess", RUN{builtin}+="uaccess" + +LABEL="wireview_end" +EOF +``` + +> [!WARNING] +> The rule sets `GROUP="dialout"`. If the `dialout` group does not exist on your distro, udev silently ignores the rule (the node stays `root:uucp`). Create it first: `sudo groupadd dialout`. + +Then reload the rules and apply them to an already-plugged device (a reload alone only affects future hotplugs): + +```sh +sudo udevadm control --reload-rules +sudo udevadm trigger +``` + +## 2. Port access + +- **NVCurve web server (systemd):** runs as root, so it can open the port as soon as the rule is in place — nothing else to do. +- **CLI as a regular user:** add your user to the `dialout` group, then log out/in: + + ```sh + sudo usermod -aG dialout $USER + ``` + + A running process only picks up new groups after a re-login; `sg dialout -c 'nvcurve ...'` works for a one-off. + +## 3. Verify + +```sh +lsusb | grep 0483 # 0483:5740 present +ls -l /dev/wireview-pro2 # -> /dev/ttyACM0 +``` + +With the device plugged in, start (or restart) the NVCurve server. The **WireView** tab appears in the web UI and `GET /api/wireview` returns the device info and live samples. The tab disappears when the device is unplugged and reappears on re-plug — no restart needed. + +## Alternative: wireview-hwmon kernel module + +If the official `wireview-hwmon` kernel module and its `wireviewd` daemon are installed, the daemon owns the serial port and NVCurve automatically reads the sysfs node instead. No udev rule is needed in that case. + +## USB device IDs + +| Mode | VID | PID | Description | +| --- | --- | --- | --- | +| Normal | `0483` | `5740` | STM32 CDC/ACM virtual serial port | +| DFU bootloader | `0483` | `df11` | STM32 bootloader (firmware updates only) | + +## Troubleshooting + +### WireView tab does not appear + +- `lsusb | grep 0483` — is the device visible at all (cable, USB port)? +- `ls -l /dev/wireview-pro2` — if the node is `root:uucp`, the `dialout` group is missing or the rule did not load: `sudo groupadd dialout && sudo udevadm control --reload-rules && sudo udevadm trigger`. +- Restart the NVCurve server — detection runs at startup, and the watchdog re-checks periodically afterwards. + +### `Permission denied` on the port (CLI) + +The user must be in the `dialout` group; a running process only picks up new groups after a restart/re-login. + +### Device visible but never connects + +The firmware occasionally stops answering the RTS welcome handshake (observed after USB state changes, e.g. udev re-triggers or boot) while still answering every data command. NVCurve falls back to the vendor-data reply and retries, but if it still does not connect, reset the USB device — physically unplug/replug, or without reaching for it: + +```sh +P=$(readlink -f /sys/class/tty/ttyACM0) +DEV=$(dirname "$(dirname "$(dirname "$(dirname "$P")")")") +sudo bash -c "echo 0 > $DEV/authorized; sleep 1; echo 1 > $DEV/authorized" +``` + +--- + +*The udev rule is taken from the wireview-reporter project, which uses the same access policy as the official `wireview-hwmon` module.*