ESPHome external component that exposes USB devices connected to an ESP32-S3 over TCP/IP using the USB/IP protocol.
- ESP32-S3 or ESP32-S2 (USB Host support)
- USB device connected to the board's USB port
external_components:
- source:
type: local
path: /path/to/esp32-usbip-esphome/components
components: [usbip]external_components:
- source: github://codebfu/esphom-usbip
components: [usbip]usbip:
id: usbip_main
port: 3240 # TCP port (default: 3240)
keepalive_idle: 5 # TCP keepalive idle time in seconds (default: 5)
keepalive_interval: 5 # Keepalive probe interval (default: 5)
keepalive_count: 3 # Number of keepalive probes (default: 3)
enable_hubs: false # Set true for USB hub / multi-device support (default: false)
device_count_id: usb_device_count # Optional: sensor ID for device count
sensors: # Optional: auto-update sensors per device index
- connected_id: usb_dev0_connected
inuse_id: usb_dev0_inuse
pid_id: usb_dev0_vidpid # VID:PID as "0x1234:0x5678"
busid_id: usb_dev0_busid
name_id: usb_dev0_name
ignore_vid_pid: # Optional: ignore devices by VID:PID
- "0x0781:*" # Use "*" to ignore all PIDs for that VID
ignore_busid: # Optional: ignore devices by bus ID
- "1-1"The component exposes getter functions callable from lambdas (e.g. in template sensors). Use id(usbip_main) to reference the component.
| Function | Return | Description |
|---|---|---|
get_device_vid_pid(index) |
string | VID:PID as "0x1234:0x5678" |
get_device_busid(index) |
string | Bus ID (e.g. "1-1") |
get_device_connected(index) |
bool | Device is physically connected |
get_device_inuse(index) |
bool | Device is attached to a usbip client |
get_device_count() |
int | Number of devices |
get_device_name(index) |
string | Device name |
| Function | Return | Description |
|---|---|---|
get_busid_by_vid_pid(vid, pid) |
string | Bus ID for given VID:PID |
get_name_by_vid_pid(vid, pid) |
string | Device name |
get_connected_by_vid_pid(vid, pid) |
bool | Connected state |
get_inuse_by_vid_pid(vid, pid) |
bool | In-use state |
| Function | Return | Description |
|---|---|---|
get_device_vid_pid_by_busid(busid) |
string | VID:PID as "0x1234:0x5678" |
get_device_name_by_busid(busid) |
string | Device name |
get_device_connected_by_busid(busid) |
bool | Connected state |
get_device_inuse_by_busid(busid) |
bool | In-use state |
text_sensor:
- platform: template
name: "USB Device 0 VID:PID"
lambda: return { id(usbip_main).get_device_vid_pid(0) };
update_interval: 5s
- platform: template
name: "USB Device 0 BusID"
lambda: return { id(usbip_main).get_device_busid(0) };
update_interval: 5s
binary_sensor:
- platform: template
name: "USB Device 0 Connected"
lambda: return id(usbip_main).get_device_connected(0);
update_interval: 5s
- platform: template
name: "USB Device 0 In Use"
lambda: return id(usbip_main).get_device_inuse(0);
update_interval: 5stext_sensor:
- platform: template
name: "SanDisk BusID"
lambda: return { id(usbip_main).get_busid_by_vid_pid(0x0781, 0x5580) };
update_interval: 5stext_sensor:
- platform: template
name: "Device 1-1 VID:PID"
lambda: return { id(usbip_main).get_device_vid_pid_by_busid("1-1") };
update_interval: 5s- Flash the firmware to your ESP32-S3
- Connect a USB device to the board
- Device connection and disconnection is detected automatically. A manual
refresh_devices()(e.g. via a button) is normally not needed; when called, the list of known devices is logged at INFO level. - On your Linux host, run:
# List available devices
usbip list -r <device-ip>
# Attach a device (replace 1-1 with the busid from list)
sudo usbip attach -r <device-ip> -b 1-1For local development and testing, use prod.yaml:
- Copy
secrets.yaml.exampletosecrets.yamland fill in your Wi-Fi credentials. - Build and flash:
esphome run prod.yaml - The config uses the local component path and DEBUG logging for usbip, usbip_tcp, usb_device, usb_host.
- When a client attaches/detaches (e.g.
usbip attach -r <ip> -b 1-1), logs will show:OP_REQ_IMPORT: client attach busid='1-1'Client attached device: busid='1-1'→inuse=trueSocket close: client release busid='1-1'→inuse=false
- The "USB Device 0 In Use" binary sensor should reflect the attach/release state.
To enable debug logs for troubleshooting, use the ESPHome logger component.
Global debug level (all components):
logger:
level: DEBUGUSBIP-specific debug (recommended to reduce log noise):
logger:
level: INFO
logs:
usbip: DEBUG
usbip_tcp: DEBUG
usb_device: DEBUG
usb_host: DEBUGFor maximum verbosity during protocol debugging, use VERBOSE instead of DEBUG. Note that VERY_VERBOSE can impact performance and stability.
To use both usb_uart (CDC-ACM, CH340, etc.) and USBIP on the same device, see docs/migration_to_standalone_usb_host.md.