ESPHome BLE Keyboard

ESPHome BLE Keyboard

Telegram

Custom esphome component to implement a virtual BLE keyboard.

More info

Supported OS

OS Description
Windows Fully supported
Linux Fully supported
Android Fully supported
MacOS It does not work stably
IOS It does not work stably

Base configuration

Requirements

  • Board: esp32, esp32s2, esp32s3, esp32c3 and esp32h2;
  • Framework: arduino.

Adding a component

external_components:
  - source: github://dmamontov/esphome-blekeyboard

Configuration

ble_keyboard:
  id: mamontech_keyboard
  name: "MamonTechKeyboard"
  manufacturer_id: "MamonTech"
  battery_level: 50
  reconnect: true
  buttons: true
  use_default_libs: true
  • id (Optional, string): Component ID. Needed for action;
  • name (Optional, string): Keyboard name (default: Esp32BleKeyboard);
  • manufacturer_id (Optional, string): Keyboard manufacturer (default: Esp32BleKeyboard);
  • battery_level (Optional, int): Keyboard battery level (default: 100);
  • reconnect (Optional, bool): Automatic reconnect service after disconnecting the device. (default: true);
  • buttons (Optional, bool): Whether to add separate buttons for keys (default: true);
  • use_default_libs (Optional, bool): Whether to use the arduino standard library. In recent versions of frameworks, they come by default. Actual for esp32s2, esp32s3, esp32c3 and esp32h2. (default: true).

Actions

ble_keyboard.print

Print arbitrary text.

ble_keyboard.print:
  id: my_ble_keyboard 
  text: "hello"
  • id (Required, string): Component ID;
  • text (Required, string): The text to be printed. Supports lambda.

ble_keyboard.press

Press a key.

ble_keyboard.press:
  id: my_ble_keyboard 
  code: 0x80

For media keys:

ble_keyboard.press:
  id: my_ble_keyboard 
  code:
    - 0
    - 1
  • id (Required, string): Component ID;
  • code (Required, int|list[int]): Key code. Supports lambda for int only.

ble_keyboard.release

Release keys.

ble_keyboard.release: my_ble_keyboard

ble_keyboard.combination

Press a key combination.

ble_keyboard.combination:
  id: my_ble_keyboard
  delay: 8
  keys:
    - 0x80 # Left CTRL
    - "a"
  • id (Required, string): Component ID;
  • delay (Required, int): Delay between clicks. Supports lambda;
  • keys (Required, list[int, string]): Key list. Doesn’t support lambda.

ble_keyboard.start

Start advertising.

ble_keyboard.start: my_ble_keyboard

ble_keyboard.stop

Stop advertising and disable customers.

ble_keyboard.stop: my_ble_keyboard

Credits

8 Likes

Telegram

Changes in v2.0.0

:exclamation::exclamation::exclamation: Warning! This version implements a full-fledged ESPHome component. It is not compatible with the previous ones.

BREAKING CHANGES

  • The component has been completely rewritten
1 Like

Telegram

Changes in v2.1.0

BREAKING CHANGES

  • Added new action ble_keyboard.combination. Allows you to execute a key combination with its own delay;
  • Added a buttons setting that allows you to disable the automatic generation of buttons for each key.

Hi, great project, thank you for sharing it with the community.
I’m trying to use it to control an nvidia shield, I have been able to do almost everything except for the menu, I haven’t found the right code.
I would also like to be able to control the fast farward and rewind functions, is this possible?
Again thank you for the effort this project is realy useful and is also faster than using adb.

Unfortunately, I can’t advise. I think it is necessary to look for codes or their combinations. I had an idea to develop a separate component that would allow them, on the contrary, to be intercepted from the original consoles. I think I’ll implement it as soon as I have time.

1 Like

Understood, thank you.
Just another question, I’m trying to create a button that sends the KEY_MEDIA_PLAY_PAUSE, I used the following code, but it returns the error “Expected integer, but cannot parse {8, 0} as integer”

button:
  - platform: template
    name: "Play"
    on_press:
      - ble_keyboard.press:
          id: keyboard 
          code: "{8, 0}"
      - ble_keyboard.release: keyboard

I feel like I’m missing something obvious, but can’t understand what.

I can add a separate action for the media. I didn’t think they were really needed. )

Telegram

Changes in v2.2.0

BREAKING CHANGES

  • Added the ability to send media keys to action press. Example.
1 Like

Hi dmamontrov,
great project you started there. Unfortatnely with my new ESP32-C3 I do get all the time the following error messages which let the deploy abord. Any suggestion how to slove that?
Or is there something else wrong?

In file included from src/esphome/components/ble_keyboard/ble_keyboard.cpp:3:
src/esphome/components/ble_keyboard/ble_keyboard.h:7:10: fatal error: BleKeyboard.h: No such file or directory

*********************************************************************
* Looking for BleKeyboard.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:BleKeyboard.h"
* Web  > https://registry.platformio.org/search?q=header:BleKeyboard.h
*
*********************************************************************

 #include <BleKeyboard.h>
          ^~~~~~~~~~~~~~~
compilation terminated.
*** [/data/c3u/.pioenvs/c3u/src/esphome/components/ble_keyboard/ble_keyboard.o] Error 1
In file included from src/esphome/components/ble_keyboard/button.h:7,
                 from src/esphome/components/ble_keyboard/button.cpp:3:
src/esphome/components/ble_keyboard/ble_keyboard.h:7:10: fatal error: BleKeyboard.h: No such file or directory

*********************************************************************
* Looking for BleKeyboard.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:BleKeyboard.h"
* Web  > https://registry.platformio.org/search?q=header:BleKeyboard.h
*
*********************************************************************

 #include <BleKeyboard.h>
          ^~~~~~~~~~~~~~~
compilation terminated.
*** [/data/c3u/.pioenvs/c3u/src/esphome/components/ble_keyboard/button.o] Error 1
========================= [FAILED] Took 57.89 seconds =========================

@gekberlin please create an issue on github and attach your yaml. I will check.

Telegram

Changes in v2.3.0

BREAKING CHANGES

  • Added advertising management;
  • Added battery level management;
  • Added support for esp32s2, esp32s3, esp32c3 and esp32h2.

BUGFIXES

  • Fixed bug when pressing default buttons.

how about the opposite direction? i.e. real ble keyboards/remote controllers integrated into esphome/ha?

Hello I’m trying to use this as a play pause remote for my android phone it connects and all that but when I try pressing play/pause key it keeps the key pressed so it just keeps pausing and playing all the time and pressing release key don’t help it only stops when I press another key and then that key is pressed.

I also tried volume up and down and it keeps pressing until max or min volume and keeps pressing

i have tried different delay press/release and also this in my yam file

  - platform: template
    name: "play_pause"
    id: key_play_pause
    on_press:
      then:
        - ble_keyboard.press:
            id: my_ble_keyboard
            code:
              - 8
              - 0
        - delay: 100ms
        - ble_keyboard.release: my_ble_keyboard

it still keeps it pressed
I’m not sure what else to try?

2 Likes

so it appears it does not release they media keys property with bleKeyboard.releaseAll();
when I make this change in ble_keyboard.cpp

void Esp32BleKeyboard::press(MediaKeyReport key, bool with_timer) {
  if (this->is_connected()) {
    if (with_timer) {
      this->update_timer();
    }
    bleKeyboard.press(key);
		delay(100);//<--
	bleKeyboard.release(key);//<--
  }
}

it works perfectly, thank you for all the work you put into this. Now I can use my ikea volume knob for pause play and volume when I play audiobooks from my phone to my google speaker.

2 Likes

This is great!
I managed to solved an annoying issue I had with this project,
I have a Xiaomi mi box S, that disconnects from WiFi in sleep mode, so there is no way to wake the device up from sleep without the remote.
Figured out the remote is just a BLE HID device and the Xiaomi box keeps the Bluetooth on when it’s in sleep mode.
Flashed an esp32 with the project on it, paired with the Xiaomi box, and now I can just send a key to wake the device up, finally I can fully control it with home assistant!
So a huge thank you for this!

I do have a question - do you know what is the key code or key combination to lock (or sleep) an android device?
I have a Logitech Bluetooth keyboard that when I press fn + “L” it locks the android device it is connected to, the same key combination also put a windows machine to sleep when it is connected to one.
Do you think this functionality can be achieved with esp BLE keyboard?

Thank you again, appreciated! :grin:

3 Likes

I think it’s possible. But you need to find a code. Somehow in the vastness of the network I met combinations for various actions with Android. I’ll try to search and add to the examples.

Telegram

Changes in v2.3.1

BREAKING CHANGES

  • The use_default_libs option is now false by default.

BUGFIXES

  • Fixed compilation error for EspHome >= 2022.12.0.
1 Like

I have the same issue with a fresh install on an Android TV.
How do you edit such file?

Hi there, I’m pretty new to ESP Home in general and am working to get this set up. I took the .yaml from the ESP32 example in the github and changed the stuff for my own names.

esphome:
  name: family-room-bt-keyboard
  friendly_name: family_room_bt_keyboard

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "redacted"

ota:
  password: "redacted"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Family-Room-Bt-Keyboard"
    password: "redacted"

captive_portal:


substitutions:

  # Software configuration
  input_text_entity_id: "input_text.blekeyboard_new_message" # A string object for entering arbitrary text.


########### End user configuration ###########


############# Base configuration #############

# Enable components
external_components:
  - source:
      type: local
      path: ../components
#  - source: github://dmamontov/esphome-blekeyboard

ble_keyboard:
  id: HA_Family_Room_Keyboard
  name: "HA Family Room Keyboard"
  manufacturer_id: "Wolfe"
  reconnect: true
  battery_level: 50
  buttons: true

text_sensor:
  - platform: homeassistant
    id: input_text
    entity_id: $input_text_entity_id
    internal: true

sensor:
  - platform: wifi_signal
    name: "WiFi Signal"
    update_interval: 60s

button:
  - platform: restart
    entity_category: "config"
    name: "Restart"

  - platform: template
    name: "Release"
    id: key_release
    icon: "mdi:send"
    on_press:
      then:
        - ble_keyboard.print:
            id: HA_Family_Room_Keyboard
            text: !lambda "return id(input_text).state;"
        - ble_keyboard.release: HA_Family_Room_Keyboard

  - platform: template
    name: "Ctrl + A"
    id: key_ctrl_a
    icon: "mdi:vector-combine"
    on_press:
      then:
        - ble_keyboard.combination:
            id: HA_Family_Room_Keyboard
            delay: 8
            keys:
              - 0x80
              - "a"

  - platform: template
    name: "Calc"
    id: key_calc
    icon: "mdi:calculator"
    on_press:
      then:
        - ble_keyboard.press:
            id: HA_Family_Room_Keyboard
            code:
              - 0
              - 2

  - platform: template
    name: "Start advertising"
    id: start_advertising
    icon: "mdi:play"
    on_press:
      then:
        - ble_keyboard.start: HA_Family_Room_Keyboard

  - platform: template
    name: "Stop advertising"
    id: stop_advertising
    icon: "mdi:stop"
    on_press:
      then:
        - ble_keyboard.stop: HA_Family_Room_Keyboard

However, when I go to install this, I see the following error:

INFO ESPHome 2023.7.1
INFO Reading configuration /config/esphome/family-room-bt-keyboard.yaml...
Failed config

external_components: [source /config/esphome/family-room-bt-keyboard.yaml:46]
  - source: 
      type: local
      
      Could not find directory '/config/esphome/../components'. Please make sure it exists (full path: /config/components).
      path: ../components

I feel like I’m missing something obvious, but I am sort of out of my element with .yaml config. Any advice?

Edit: I went back to the main page and copied just what was in the blocks:

external_components:
  - source: github://dmamontov/esphome-blekeyboard

ble_keyboard:
  id: HA_BT_Keyboard
  name: "HA BT Keyboard"
  manufacturer_id: "Wolfe"
  battery_level: 50
  reconnect: true
  buttons: true
  use_default_libs: false

This does install and I can see and adopt the device in HA, however I have no idea how to initiate the connection to the Nvidia Shield I’m trying to connect to. How do you do this?

One last edit: Apparently you just select the HA keyboard from the device itself as it’s always available for pairing lol.

Is it possible to trigger actions by firing a HA event? Or do all keypresses have to be initiated using the device controls?

image