[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81803":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":26,"readmeContent":27,"aiSummary":28,"trendingCount":15,"starSnapshotCount":15,"syncStatus":16,"lastSyncTime":29,"discoverSource":30},81803,"usbeehive","abrauchli\u002Fusbeehive","abrauchli","Tells you what each USB cable \u002F device on Linux can actually do. Rust port of WhatCable; previously published as `whatcable`.","https:\u002F\u002Fgithub.com\u002Fabrauchli\u002Fusbeehive",null,"Rust",58,1,3,0,2,5,20,6,0.9,"MIT License",false,"master",true,[],"2026-06-12 02:04:19","# usbeehive 🐝\n\n> **What can this USB cable actually do?**\n\nA command-line tool, and a Rust library, that tell you in plain English\nwhat each USB device plugged into your Linux machine can actually do.\n\n**usbeehive is a Linux port of [WhatCable](https:\u002F\u002Fgithub.com\u002Fdarrylmorley\u002Fwhatcable),\na macOS menu-bar app by [Darryl Morley](https:\u002F\u002Fgithub.com\u002Fdarrylmorley).**\nThis port covers all USB devices, not just USB-C, while preserving the\nrich USB-C Power Delivery diagnostics from the original.\n\nThe Rust rewrite is forked from\n[Zetaphor\u002Fwhatcable-linux](https:\u002F\u002Fgithub.com\u002FZetaphor\u002Fwhatcable-linux)\n(originally C++ \u002F CMake).\n\n> **Renamed from `whatcable`.** This project was previously published on\n> crates.io as [`whatcable`](https:\u002F\u002Fcrates.io\u002Fcrates\u002Fwhatcable) — at the\n> original author's request, it has been renamed to `usbeehive` as of\n> 0.5.0. The old crate is retired (its final release is a redirect to\n> here). Use `cargo install usbeehive` going forward.\n\n## What it shows\n\n### All USB devices\n- **Identity**: vendor, product name, serial number\n- **Speed**: negotiated link speed (1.5 Mbps to 20 Gbps)\n- **USB version**: 1.1, 2.0, 3.0, 3.1, 3.2\n- **Power draw**: how much power the device is consuming\n- **Device type**: HID, Audio, Mass Storage, Hub, etc.\n- **Driver**: which kernel driver is handling the device\n- **Topology**: hub hierarchy showing what's plugged into what\n\n### USB-C ports (additional detail)\n- **Port roles**: data role (host\u002Fdevice), power role (source\u002Fsink)\n- **Cable e-marker info**: cable speed capability, current rating (3A\u002F5A), active vs passive, cable vendor\n- **Charger PDO list**: every voltage \u002F current profile the charger advertises, with the active profile highlighted\n- **Charging diagnostics**: identifies bottlenecks — cable limiting speed, charger undersized, etc.\n- **Live wattage** (UCSI): `voltage_now × current_now`, exposed as `negotiatedPowerMW` in JSON output and via `TypeCPowerSupply::negotiated_power_mw()` in the library.\n- **Partner identity**: decoded from PD Discover Identity VDOs\n\n## Install\n\n### From crates.io\n\n```bash\ncargo install usbeehive\n```\n\n### Build from source\n\nRequires Rust 1.85+ ([rustup](https:\u002F\u002Frustup.rs)) and `libudev` development\nheaders (for `--watch` hotplug support, on by default).\n\n```bash\n# Ubuntu \u002F Debian\nsudo apt install libudev-dev pkg-config\n\n# Fedora\nsudo dnf install systemd-devel pkgconf-pkg-config\n\n# Arch \u002F Manjaro\nsudo pacman -S --needed systemd-libs pkgconf\n```\n\n```bash\ncargo build --release                                  # default (with --watch)\ncargo build --release --no-default-features --features cli,sysfs    # no libudev\nsudo install -Dm755 target\u002Frelease\u002Fusbeehive \u002Fusr\u002Flocal\u002Fbin\u002Fusbeehive\n```\n\n### Tests\n\n```bash\ncargo test                                # full suite (requires libudev-dev)\ncargo test --no-default-features          # pure-decoder subset, no libudev\n```\n\n## CLI usage\n\n```bash\nusbeehive                                  # human-readable summary of every USB device\nusbeehive --json                           # structured JSON output\nusbeehive --watch                          # stream updates as devices come and go\nusbeehive --raw                            # include raw sysfs attributes\nusbeehive --sysfs-root \u002Ftmp\u002Ffixture-root   # run against a captured tree (testing)\nusbeehive --version\nusbeehive --help\n```\n\n## Library usage\n\nThe crate has three optional layers, each behind a Cargo feature so\nconsumers pull in only what they need.\n\n| Feature | Default | Adds |\n|---|---|---|\n| (none) | always | Data types, USB-PD VDO decoders, diagnostics, summaries — IO-free. |\n| `sysfs` | yes | `Sysfs` handle + `DeviceManager` — Linux `\u002Fsys` enumeration with injectable root. |\n| `watch` | yes | libudev hotplug monitor: `watch::Watcher` + `watch::run_loop`. |\n| `cli` | yes | The `usbeehive` binary (clap + JSON \u002F text rendering). |\n| `dbus` | no | `usbeehive::dbus` interface module + the `usbeehived` daemon binary publishing `org.usbeehive.Devices3` on the session bus (implies `watch`). |\n\nLibrary-only consumers can drop the binary deps:\n\n```toml\n# Pure decoders, no IO, no libudev:\nusbeehive = { version = \"0.5\", default-features = false }\n\n# Add \u002Fsys enumeration:\nusbeehive = { version = \"0.5\", default-features = false, features = [\"sysfs\"] }\n\n# Add hotplug too:\nusbeehive = { version = \"0.5\", default-features = false, features = [\"watch\"] }\n```\n\n### Decode a Cable VDO\n\n```rust\nuse usbeehive::pd::{decode_cable_vdo, CableSpeed, CableCurrent};\n\nlet v = decode_cable_vdo(2 | (2 \u003C\u003C 5) | (3 \u003C\u003C 9), false);\nassert_eq!(v.speed, CableSpeed::Usb32Gen2);\nassert_eq!(v.current_rating, CableCurrent::FiveAmp);\nassert_eq!(v.max_watts, 250);\n```\n\n### Enumerate the system's USB tree\n\n```rust,no_run\nuse usbeehive::DeviceManager;\n\nlet mut mgr = DeviceManager::new();\nmgr.refresh();\nfor s in mgr.devices() {\n    println!(\"{}: {}\", s.headline, s.subtitle);\n}\n```\n\n### Run a debounced render loop on hotplug events\n\n```rust,no_run\nuse std::time::Duration;\nuse usbeehive::{watch::run_loop, DeviceManager};\n\nlet mut mgr = DeviceManager::new();\nrun_loop(Duration::from_millis(500), |_reason| {\n    mgr.refresh();\n    println!(\"snapshot has {} devices\", mgr.devices().len());\n    Ok(())\n}).unwrap();\n```\n\nSee [`examples\u002F`](examples) for more.\n\n## D-Bus daemon (optional)\n\nBuild with the `dbus` feature to get a long-running daemon, `usbeehived`,\nthat publishes the live snapshot on the session bus. Useful for desktop\napplets (KDE \u002F GNOME \u002F tray apps) that want to react to cable plugs and\ncharging-bottleneck changes without each one re-implementing sysfs\nenumeration.\n\n```bash\ncargo build --release --no-default-features --features dbus\n.\u002Ftarget\u002Frelease\u002Fusbeehived                                # foreground\n```\n\nWire surface — `org.usbeehive.Devices3` at `\u002Forg\u002Fusbeehive\u002FDevices`:\n\nEach `ListDevices` entry is a 21-field tuple:\n`(id, category, device_class, device_subclass, status, headline, subtitle, icon, vendor, product, vendor_id, product_id, primary_driver, properties, port_number, link_speed_mbps, usb_version, power, charging_diag, pdo_list, active_pdo_index)`. See [`src\u002Fdbus.rs`](src\u002Fdbus.rs) module docs for per-field semantics.\n\n| Member | Kind | Notes |\n|---|---|---|\n| `ListDevices` | method `() → a(ssssssssssqqsa(ss)ius(uus)(bsssb)a(usuuuub)i)` | One structured entry per summary. Properties are `(machine_key, value)` pairs; `pdo_list` is the structured source-PDO advertisement. |\n| `ListPorts` | method `() → ai` | Type-C `port_number`s currently exposed. |\n| `Diagnose` | method `(i) → (bsssb)` | Charging diagnostic for a port — same shape as the per-entry `charging_diag`. `present == false` when none available. |\n| `SnapshotJson` | method `() → s` | Full structured snapshot — same shape as `usbeehive --json`. |\n| `Refresh` | method `() → u` | Force a re-enumeration; returns the new device count. |\n| `Version` \u002F `DeviceCount` | properties | Crate version + summary count. |\n| `DeviceAdded` \u002F `DeviceRemoved` | signals | Fire when a device or port appears \u002F disappears. |\n| `CapabilityDegraded` \u002F `CapabilityRestored` | signals | Fire when a port's charging diagnostic newly raises (or clears) `is_warning` — e.g. a too-thin cable plugged into a beefy charger. |\n\nQuick poke from the shell:\n\n```sh\ngdbus call --session --dest org.usbeehive.Devices \\\n    --object-path \u002Forg\u002Fusbeehive\u002FDevices \\\n    --method org.usbeehive.Devices3.ListDevices\n```\n\nA minimal Rust client lives in [`examples\u002Fdbus_client.rs`](examples\u002Fdbus_client.rs).\n\n### Devices3 migration\n\n`Devices2` was retired in favor of `Devices3` — clients must update the\ninterface name and append two trailing fields to the per-entry payload\n(`pdo_list`, `active_pdo_index`). Adding new enum variants\n(`device_class`, `status`, `power_role`, `bottleneck`) is non-breaking;\nclients MUST treat any unrecognized string as `Unknown` \u002F fall back to\ncategory-based behavior. New machine-keyed properties\n(`cable.trust.*`, `transport.*`) are pushed only when their flag fires —\nabsence is the \"off\" state. The CHANGELOG has the full break-by-break\nmigration table.\n\n## How it works\n\nusbeehive reads three areas of the Linux sysfs filesystem. No root access\nrequired for basic info:\n\n| sysfs path | Provides |\n|---|---|\n| `\u002Fsys\u002Fbus\u002Fusb\u002Fdevices\u002F` | All USB devices: vendor, product, speed, power, class, interfaces, topology |\n| `\u002Fsys\u002Fclass\u002Ftypec\u002F` | USB-C port state: connection, roles, cable e-marker, partner identity |\n| `\u002Fsys\u002Fclass\u002Fusb_power_delivery\u002F` | PD negotiation: PDO list from charger, active profile, PPS ranges |\n| `\u002Fsys\u002Fclass\u002Fpower_supply\u002Fucsi-source-psy-*` | Live `voltage_now × current_now` charging readout |\n\nHotplug uses `libudev` to detect connect\u002Fdisconnect events in real time.\n\nCable speed and power decoding follow the USB Power Delivery 3.x spec,\nported from the original WhatCable's Swift implementation.\n\n## Caveats\n\n- **USB-C \u002F PD data availability varies by hardware.** The Type-C connector\n  class and USB PD sysfs interfaces depend on the kernel driver\n  (UCSI, TCPM, platform-specific). Some systems expose full PD negotiation\n  data; others expose only basic port info or nothing at all.\n- **Cable e-marker info only appears for cables that carry one.** Same as\n  the original — most USB-C cables under 60W are unmarked.\n- **usbeehive trusts the e-marker.** Counterfeit or mis-flashed cables can\n  lie about their capabilities.\n- **Vendor name lookup is not exhaustive.** Common vendors are recognized;\n  others show the hex VID.\n\n## Credits\n\nOriginal macOS app: [WhatCable](https:\u002F\u002Fgithub.com\u002Fdarrylmorley\u002Fwhatcable)\nby [Darryl Morley](https:\u002F\u002Fgithub.com\u002Fdarrylmorley) — and thanks to Darryl\nfor suggesting the new name when the Rust port outgrew its borrowed one.\nThe USB Power Delivery decoding logic, charging diagnostics, vendor\ndatabase, and plain-English summary approach are derived from the original\nmacOS app.\n\nUpstream Linux\u002FKDE C++ port: [Zetaphor\u002Fwhatcable-linux](https:\u002F\u002Fgithub.com\u002FZetaphor\u002Fwhatcable-linux).\n\n## License\n\n[MIT](LICENSE)\n","usbeehive 是一个用于 Linux 系统的命令行工具及 Rust 库，能够以通俗易懂的语言描述每个连接到系统的 USB 设备的实际功能。其核心功能包括展示 USB 设备的身份信息、速度、版本、功耗、设备类型、驱动程序以及拓扑结构等详细信息，并且对于 USB-C 接口还提供了额外的诊断信息如端口角色、电缆标志信息、充电器PDO列表及实时功率等。该工具特别适合需要对USB设备进行全面了解和故障排查的场景，比如开发人员调试硬件兼容性问题或系统管理员监控设备状态时使用。","2026-06-11 04:06:45","CREATED_QUERY"]