I saw this project for a WiFi Duck where you can use a small esp8266 as a usb keyboard to send keyboard commands to a computer using ducky script. I thought maybe this functionality to use an esp8266 as a usb HID keyboard could eventually be implemented in ESPHome. Combined with AutoHotKey, this could create some really powerful automations on your computer.
There is already this software to control a Windows PC over MQTT but the downside is that you have to install it on the PC and there are some limitations on what you can run or execute.
What are some cool automations or use-cases for a USB keyboard emulator can you think of?
I know this a pretty old thread but I’d also love to see this request implemented to ESPHome. Imho you @nickrout got the situation wrong, not @LUNZ. The purpose would not be to connect such a “WiFi Duck” to the device running Home Assistant, which, yes would be pretty pointless. You could however have full control over any computer, no matter what kind of OS it runs on. Sou you would not send a keyboard codet to home assistant but instead from home assistant to any other device. To give some real use cases:
You could unlock your computer from Home Assistant, e.g. by placing a rfid tag on a reader (the WiFi Duck would only have to enter the correct password)
You have full control over wall mounted tablets, and that’s something I’m searching a solution for since days. I have two old Microsoft Surfaces 3, which I’m planning to mount as a HA Dashboard on the wall. The problem is that I can’t find any way to turn the tablets on remotly. They of course use WiFi so Wake on Lan does not work and any local script will stop working as soon as I bring the tablets to sleep as the CPU turns off. The only way to wake them is using the power button, OR - and here comes the feature request in - using a USB keyboard.
And controlling power is not the only thing you could do with it on a wall mounted tablet:
You could automatically open VLC to open the stream of a camera based on a motion sensor or the door bell, which espically on slow devices works way better than using lovelace based streams
The browser can be controlled, e.g. opening a news page at a specific time or simply reload the Home Assistant interface if it ever should get stuck (happened a few times to me)
Edit: Here is a project which does almost exactly what I want: Use an ESP8266 as USB HID Device. Having espusb integrated to ESPHome would be awesome. I managed to run espusb on one of my ESP’s and the example programm worked perfect, you can control the Keyboard using a webinterface on any other device. However I could not find a way to integrate this into Home Assistant to automate stuff
Bottom line, yes an esp can easily emulate an hid keyboard. There are arduino libraries that make it easy to do. Not sure if they have been ported to esphome, but you could always do the arduino code yourself and use mqtt instead.
Another complicated alternative if esphome is needed (and no ported libs available) is hook an arduino nano up with uart to the esp. Nanos are the easiest arduino to setup as an hid device (using arduino libraries). Then use esphome UART to send keys to a serial port on the nano board, which is hooked to your surface usb port and will appear just like a keyboard to windows.
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.
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
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).
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…
#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
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