ESPHome external components to simulate USB HID devices (mouse, keyboard, telephony) on ESP32-S3.
| Component | Description |
|---|---|
hid_mouse |
USB HID Mouse only |
hid_keyboard |
USB HID Keyboard only |
hid_composite |
USB HID Mouse + Keyboard + Telephony combined |
hid_telephony |
USB HID Telephony only (mute/call control) |
Note: These components are mutually exclusive. Use only ONE of them in your configuration.
- Relative cursor movements (X, Y)
- Left, right, and middle buttons
- Vertical and horizontal scroll wheel
- Keep awake (prevents PC sleep)
- Key press/release/tap
- All standard keys (A-Z, 0-9, F1-F12, arrows, etc.)
- Modifier keys (Ctrl, Shift, Alt, GUI/Win/Cmd)
- Type entire text strings with realistic speed/jitter
- Keyboard shortcuts (Ctrl+C, Alt+Tab, etc.)
- Keep awake (prevents PC sleep)
- Mute/unmute control
- Answer/hang up calls
- Bidirectional sync: PC mute state is reflected in Home Assistant
- Binary sensors for call state (in_call, ringing)
- Switch component for mute control
All components provide:
is_connected()- PC connected via USB- Binary sensor for connection status
- ESP32-S3 with native USB OTG port
- ESP-IDF framework (default since ESPHome 2026.1.0)
- ESPHome 2025.8.0+ recommended (2026.1.0+ for best experience)
- Board with two USB ports recommended:
- UART/CH340 port: for flashing and serial logs
- USB native/JTAG port: for HID devices
Important: The HID device will only work on the USB native/JTAG port, not the UART/CH340 port.
# For mouse only
external_components:
- source:
type: git
url: https://github.com/AntorFr/esphome-hid
ref: main
components: [hid_mouse]
# For keyboard only
external_components:
- source:
type: git
url: https://github.com/AntorFr/esphome-hid
ref: main
components: [hid_keyboard]
# For both mouse and keyboard
external_components:
- source:
type: git
url: https://github.com/AntorFr/esphome-hid
ref: main
components: [hid_composite]esphome:
name: esp32-hid
platformio_options:
build_flags:
- -DCFG_TUD_HID=1
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf # Default since ESPHome 2026.1.0
sdkconfig_options:
CONFIG_USJ_ENABLE_USB_SERIAL_JTAG: "n"
CONFIG_TINYUSB_HID_COUNT: "1"
CONFIG_ESP_CONSOLE_UART_DEFAULT: "y"
components:
- espressif/esp_tinyusb~2.0.0hid_mouse:
id: my_mouse| Action | Description |
|---|---|
hid_mouse.move |
Move cursor (x, y: -127 to 127) |
hid_mouse.click |
Click button (LEFT, RIGHT, MIDDLE) |
hid_mouse.press |
Press button |
hid_mouse.release |
Release button |
hid_mouse.release_all |
Release all buttons |
hid_mouse.scroll |
Scroll (vertical, horizontal) |
hid_keyboard:
id: my_keyboard
layout: AZERTY_FR # Optional: QWERTY_US (default), AZERTY_FR, QWERTZ_DE| Action | Description |
|---|---|
hid_keyboard.press |
Press key |
hid_keyboard.release |
Release all keys |
hid_keyboard.tap |
Press and release key |
hid_keyboard.type |
Type text string |
The layout option configures the keyboard mapping for the type action. This must match the keyboard layout configured on the target PC:
| Layout | Description |
|---|---|
QWERTY_US |
US English (default) |
AZERTY_FR |
French AZERTY |
QWERTZ_DE |
German QWERTZ |
Note: The layout only affects the
typeaction. Actions likepress,tapsend raw scancodes and work regardless of PC keyboard settings.
ENTER, ESC, BACKSPACE, TAB, SPACE, DELETE, INSERT, HOME, END, PAGEUP, PAGEDOWN, UP, DOWN, LEFT, RIGHT, F1-F12
NONE, CTRL, SHIFT, ALT, GUI (WIN/CMD), CTRL_SHIFT, CTRL_ALT, CTRL_GUI, etc.
# Type text
- hid_keyboard.type:
text: "Hello World!"
# Ctrl+C
- hid_keyboard.tap:
key: "c"
modifiers: CTRL
# Alt+Tab
- hid_keyboard.tap:
key: "TAB"
modifiers: ALThid_composite:
id: my_hid
layout: AZERTY_FR # Optional: QWERTY_US (default), AZERTY_FR, QWERTZ_DEMouse: hid_composite.move, hid_composite.click, hid_composite.mouse_press, hid_composite.mouse_release, hid_composite.scroll
Keyboard: hid_composite.key_press, hid_composite.key_tap, hid_composite.key_release, hid_composite.type
Telephony: hid_composite.mute, hid_composite.unmute, hid_composite.toggle_mute, hid_composite.answer_call, hid_composite.hang_up
Keep Awake: hid_composite.start_mouse_keep_awake, hid_composite.stop_mouse_keep_awake, hid_composite.start_keyboard_keep_awake, hid_composite.stop_keyboard_keep_awake
hid_telephony:
id: my_telephony| Action | Description |
|---|---|
hid_telephony.mute |
Send mute button press |
hid_telephony.unmute |
Send unmute button press |
hid_telephony.toggle_mute |
Toggle mute state |
hid_telephony.answer |
Answer incoming call |
hid_telephony.hang_up |
End current call |
binary_sensor:
- platform: hid_composite # or hid_mouse, hid_keyboard, hid_telephony
type: connected
name: "PC Connected"binary_sensor:
- platform: hid_composite
type: in_call
name: "In Call"
- platform: hid_composite
type: ringing
name: "Ringing"switch:
- platform: hid_composite
type: mouse
name: "Mouse Keep Awake"
interval: 60s
jitter: 10s
- platform: hid_composite
type: keyboard
name: "Keyboard Keep Awake"
key: "F15"
interval: 60sswitch:
- platform: hid_composite
type: mute
name: "Mute"Note: The mute switch syncs bidirectionally with the PC. If mute is toggled via Teams/Zoom, the switch updates automatically.
See the examples folder:
- basic.yaml - Mouse
- keyboard.yaml - Keyboard
- composite.yaml - Mouse + Keyboard
- test_composite_switch.yaml - Composite with switches
- test_telephony.yaml - Telephony controls
MIT License