[Feature Request] Using ESPHome to emulate a usb keyboard

Yes, at the end of the day github is the final stage for feature adds. So might as well start there to fast forward the process a bit. This idea does sound like it would have popular applications. So would be nice to see an official esphome component for it, vs custom components and how to guides.

1 Like

That was also my thought, however espusb uses websockets for communication between the webinterface and the backend. So sadly it’s not as easy.

No, the Arduino HID librariers only work an Arduino Boards based on the Atmega32u4, such as the Leonardo, as they need access to the specific Hardware Features of this microcontroller. That’s why it also can’t work on a Nano. espusb doesn’t need those specific hardware features as it completely emualtes the usb interface using bitbanging (if I got it right).

That’s what makes the whole thing that complicated. Also I realized espusb sadly seems kind of abandoned and to compile it you need a specific old version of the esp sdk. That makes it probably very hard if not impossible to add it as ESPHome component…

That’s probably the only alternative, when wanting to use ESPHome but it would require an Atmega32u4 Board as described above.

Also I just found out that the Raspberry Pi Zero seems to have HID capabilities. I’ll give it a try tomorrow

1 Like

No, github is the starting point for esphome feature requests.

Shoot, did I say nano? I meant micro lol. You knew what I meant anyways. :slight_smile:

1 Like

One option would be to emulate a bluetooth keyboard, and skip the USB altogether. This device made me think of it Bluefruit EZ-Key - 12 Input Bluetooth HID Keyboard Controller - v1.2 - discontinued, but they probably make something else now.

1 Like

Another option is to get the chip out of a disused USB keyboard. They are simply a matrix - you could wire that to an esp.

1 Like

I’ve earlier used an ESP32 with BLE Keyboard code, using MQTT to communicate with HA. This way I could send keystrokes to the ESP32 which again control my satellite receiver (support BT remote).

1 Like

Wow that’s a great idea!

A quick google search shows that someone was using this to remotely unlock their iPad. I’m sure there are some other interesting use cases too

@TheStigh can you share a link to the project that you used that has mqtt support?

@LUNZ Can see if I find the Arduino project and share it with you :slight_smile:

1 Like

This version I’ve kept the debugging versions.
Using a WEMOS D1 MINI ESP32
Than letting my remote pair to this ESP as a remote.
Sending MQTT messages to what channel you want to switch to… :slight_smile:

#include <PubSubClient.h>
#include <WiFi.h>
#include <BleKeyboard.h>

#define BLETOPIC "BLE/command"
#define SERVICETOPIC "SERVICE/service"

int STATUS_PIN = 2;

WiFiClient client;
BleKeyboard bleKeyboard("ESP32 BT Remote", "Espressif", 100);



char *ssid      = "<WIFI>";
char *password  = "<PASSWORD>";
const char* mqtt_server = "<IP>";
const char* mqtt_user = "<USER>";
const char* mqtt_password = "<PASSWORD>";
unsigned long previousMillis = 0;
unsigned long interval = 30000;


void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
//  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
//    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  } 
  Serial.println();
  Serial.print("Changing to channel : ");
  Serial.print(messageTemp);
  bleKeyboard.print(messageTemp);
  Serial.println();
  Serial.println("-----------------------");
//  Serial.print("Sending Enter key...");
//  bleKeyboard.write(KEY_RETURN);
//  Serial.println();
//  Serial.println();
}

PubSubClient mqtt(mqtt_server, 1883, callback, client);

void setup() {

  Serial.begin(115200);
  
  pinMode(STATUS_PIN, OUTPUT);
  digitalWrite(STATUS_PIN, HIGH);

  Serial.println();
  Serial.println("Connecting to WiFi...");
  WiFi.mode(WIFI_STA);
  WiFi.begin (ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.println(WiFi.localIP());
  Serial.println();
  Serial.println("WiFi connected");

  connectMQTT();

  Serial.println();
  Serial.println("Starting BLE...");
  bleKeyboard.begin();


  Serial.println();
  Serial.println("Setup Done!");
}

void loop() {
//  if (bleKeyboard.isConnected()) {
//    Serial.println("BLE OK!");
//  }

  unsigned long currentMillis = millis();
  // if WiFi is down, try reconnecting
  if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >=interval)) {
    Serial.print(millis());
    Serial.println("Reconnecting to WiFi...");
    WiFi.disconnect();
    WiFi.reconnect();
    previousMillis = currentMillis;
  }

  mqtt.loop();

}


/******************************************************************************
 ****                                                                      ****
 ****                         connectMQTT                                  ****
 ****                                                                      ****
 *****************************************************************************/

void connectMQTT() {
  while (!mqtt.connected()) {
    Serial.println("Attempting MQTT connection...");
    if (mqtt.connect("ESP32 BT Remote", mqtt_user, mqtt_password)) {
      Serial.println("connected");
      mqtt.publish(SERVICETOPIC, "ESP32 BT Remote are now Live");
      Serial.println("Connection information sent to MQTT broker!");
      mqtt.subscribe(BLETOPIC,1);
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqtt.state());
      Serial.println(" try again in 2 seconds");
      // Wait 2 seconds before retrying
      delay(2000);

    }
  }
}


/******************************************************************************
 ****                                                                      ****
 ****                         publishMQTT                                  ****
 ****                                                                      ****
 *****************************************************************************/
 
void publishMQTT(String topic, String message) {
  if (!mqtt.connected()) {
    reconnectMQTT();
  }
  mqtt.publish(topic.c_str(), message.c_str());
}


/******************************************************************************
 ****                                                                      ****
 ****                        reconnectMQTT                                 ****
 ****                                                                      ****
 *****************************************************************************/
 
void reconnectMQTT() {
  // Loop until we're reconnected
  while (!mqtt.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (mqtt.connect("ESP32 BT Remote")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      mqtt.publish(SERVICETOPIC, "ESP32 BT Remote are Live again");
      // ... and resubscribe
      mqtt.subscribe(BLETOPIC,1);
    } else {
      Serial.print("failed, rc = ");
      Serial.print(mqtt.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

Have you seen this?
It creates an Esphome project which can read IR codes and sends BLE HID keyboard keys.
The project includes the YAML file and the custom BLE component as a header file for the BLE HID keyboard. It uses the well-known library https://github.com/T-vK/ESP32-BLE-Keyboard

3 Likes

Collected based on my firmware: GitHub - dmamontov/esphome-blekeyboard: ESPHome BLE Keyboard
I think this is what will suit you.

4 Likes

I think here:

 libraries:
    - ESP32 BLE Arduino@>=1.0.1
    - https://github.com/T-vK/ESP32-BLE-Keyboard/releases/download/0.3.0/ESP32-BLE-Keyboard.zip  

That’s looking for something else to include called “sdkconfig.h” which doesn’t have an external URL or anything.
I wonder if we can find out what that is and move all of these libraries to the ESPHome folder.
I got out of Arduino stuff for this reason lol

I think you should update both ESPHome and pio. On the most recent version, everything is definitely fine.

ESPHome is fully updated, what is pio?

pio = PlatformIO

Ok I see what that is.
Is that required to get this to work somehow?
I use the VSCode add-on, but for editing ESPHome code I just use the ESPHome add-on itself…

1 Like

esphome uses it and if you google your error, then there are recommendations to update it everywhere, because this is the absence of a system library)

Maybe you’ll find this interesting: ESPHome Ducky

1 Like

Wow! Great work putting this together - I’m very impressed.

Can’t wait to get some parts and put this together!