Very slow response to remote commands

Hi
I used to have 2 Apple TV device but have upgraded to Shield TV devices and have noticed massive delays in sending remote commands.
When I was using the Apple TV devices the remote commands were very snappy with very minimal lag perhaps 1 millisecond.
How ever the Android TV integration is horrible its adding significant delays between each command.
This is annoying when trying to navigate Plex or Netflix to scroll through media.
I have put up with this for a few months now but this got 10 times worse with the recent update to Home assistant as the Android TV integration added the screen cap feature ( No way to disable this yet :frowning: )

I understand that the process of sending the commands to the shield TV via ADB could be adding delays and now since the screen caps are coming through via ADB also its slowing things down alot more.

If I install the Android TV app on my phone the navigation is perfect and 100 times faster than what I’m getting via Home assistant.

So I had a Harmony hub sitting spare so I decided to get this setup and tested everything through the harmony app and its perfect exactly like using the android TV app.
I setup the harmony hub integration and got this working but the lag is the same as it was with ADB ( Prior to the screen cap feature being added)

So now I’m thinking maybe this is some sort of limitation of Home assistant but since the Apple TV integration worked fine I don’t know what to think now its annoying the hell out of me

I have designed my whole home assistant front end around having a single app to control everything in my house. I’m not just sending remote commands as part of automation I’m using remote commands to completely replace the psychical remote the lag almost makes it un usable.

Just wondering if anyone has had the same issues and managed to fix the delay or if anyone knows why this is happening?

1 Like

Can you test something for me? I use xiaomi Android TV box. It is also slow when I use an app. For me that was solved by disabling hdmi-cec control.

I’ve fully disabled HDMI-CEC but that made no difference unfortunately.

Ok, to bad. Thank you for trying though. Have you got a lot of other app’s on the shield? I’ve also disabled all apps I don’t use. Things like Google calendar and Roku. So I only have YouTube, Kodi and Spotify enabled now. That helped a little too. Not as much as disabling hdmi-cec though, but maybe that’s a xiaomi thing.

Both shield TV’s have bear-bones apps on them.
I don’t think its the shield its self i’m thinking its the interface between home assistant and the harmony hub seems like there is a massive delay being added in somewhere.
If it use the Harmony remote app its perfect no perceivable lag what so ever.
seems the majority of people don’t use home assistant in this way to replace a physical remote.
I will keep looking for solutions :slight_smile: thanks for trying to help.

Ok, that is weird, since ADB and the harmony show the same delay’s but other “remotes” don’t. And if you use the HA+harmony to control a normal tv or something does is also show these delays?

My adb commands worked ok and then slowed down recently after .108. I just removed the media card since I only used the power on/off and that fixed the long delay. I think the media card trying to display what was playing used to much bandwidth, just a guess.

I am having the same issue with android box too.

seems that you can disable the screencap on the media player with yaml config. It help a bit, but I still have less than 1 second delay. I will see, if it won’t get worse.

Similar issues here with adb commands :confused: cannot find a solution

First, disable the screencap option. Then try this: https://www.home-assistant.io/integrations/androidtv/#androidtvlearn_sendevent-for-faster-adb-commands

Yes it’s better with sendevent … will test without the screencap option as well later. Thank Jeff

When I try send the command for the send event that was found during the learning process I get an error saying “No such file or directory” any ideas ?

I found out that If the remote goes into sleep mode or disconnects then the events don’t work.
also tried learning the event codes from the shield TV app but this also disconnects and needs to be re opened again for the commands to work.
it definitely solves the speed issue but if you have to wake the remote or reconnect the app this makes it useless to use.
Any one know how to stop the remote going to sleep ?

1 Like

Someone mentioned that point about the remote going to sleep on Discord. I don’t know whether that’s the cause or not, but I’ll take your word for it.

I have two Fire TV sticks. On one of them I’ve been using sendevent commands for weeks without issue. On the other (which is not currently in use), I recently tried using sendevent commands but got the error you mentioned. Some possible reasons for this could be:

  • The second device was powered by the TV, not plugged into an outlet, so maybe something is going to sleep because of that?
  • For the second device, I had to change the remote batteries before testing it, so maybe the fact that the remote had been without power prior to my experiment caused the command to fail?

I have two Shield TV’s in my rack directly connected to power and remotes shows as fully charged.
Must be something to do with the Shield TV FW and the hardware.
It seems that every time the remote or App disconnect their event mapping is removed and re-added when they reconnect.

I did manage to get what appears to be a working solution using a harmony hub combined with the send events command as the harmony hub connects as a Bluetooth keyboard all I have to do is call an activity for each box to connect the Bluetooth this enables the send events to be recognized.
I did try just using the harmony integration directly but the input lag was still there not sure if that’s because of my old hub.
I was also going to try just plugging in a keyboard to each box and mapping the keys… Ill save that as a last resort :slight_smile:
Thanks for you help and advise.

Hey is this the truly case? I have a Chromecast with GoogleTV and I can’t get the learned commands to work even if the remote was just used. Any luck with this?

I got frustrated with the slowness over ADB so I made my own solution - making a pi zero w (or pi zero w 2) act like a USB Keyboard and plugged it into my FireTV / Chromecast with Google TV).

I’ve released the receiver here, I’m still working on a sender. However it has a lot of ways to send commands to it that you should be able to hook it into Home Assistant.

I’ve just upgraded to v0.3.0 which allows push and hold - I’m transmitting a USB remote to the Android TV box in my loft and to me it feels like it works as fast as if I was using the remote directly including pushing/holding/releasing keys on my USB remote.

I had a similar idea, but approached it differently. It looks like Nvidia have changed the security for the sendevent commands which means you’re stuck with extremely laggy input on the remote.

My approach was using an ESP32 and emulating a Bluetooth remote. It works perfectly.

I’m by no means a coder, but it runs fine. Let me know if it’d be helpful for anyone and I’ll post the code and instructions.

Yes please can you post the code. It would be interesting to see.

I’ll post both the code and the platformio config. I think that should give you what you need, but again let me know if you need anything else.

Code

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

BleKeyboard bleKeyboard;
const char* mqtt_server = "<MQTT Server IP Address>";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup() {
  Serial.begin(115200);
  setup_wifi();
  bleKeyboard.begin();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

}

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to WiFi");

  WiFi.begin(<SSID>, "<PASSWORD>");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

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();


  if (String(topic) == "iot/remote/control") {
    if (messageTemp == "Stop"){
      Serial.println();
      client.publish("iot/remote/result", messageTemp.c_str());
      bleKeyboard.write(KEY_MEDIA_STOP);
    }
    else if (messageTemp == "PP"){
      Serial.println();
      client.publish("iot/remote/result", messageTemp.c_str());
      bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE);
    }
    else if (messageTemp == "Mute"){
      Serial.println();
      client.publish("iot/remote/result", messageTemp.c_str());
      bleKeyboard.write(KEY_MEDIA_MUTE);
    }
    else if (messageTemp == "Up"){
      Serial.println();
      client.publish("iot/remote/result", messageTemp.c_str());
      bleKeyboard.write(KEY_UP_ARROW);
    }
    else if (messageTemp == "Down"){
      Serial.println();
      client.publish("iot/remote/result", messageTemp.c_str());
      bleKeyboard.write(KEY_DOWN_ARROW);
    }
    else if (messageTemp == "Left"){
      Serial.println();
      client.publish("iot/remote/result", messageTemp.c_str());
      bleKeyboard.write(KEY_LEFT_ARROW);
    }
    else if (messageTemp == "Right"){
      Serial.println();
      client.publish("iot/remote/result", messageTemp.c_str());
      bleKeyboard.write(KEY_RIGHT_ARROW);
    }
    else if (messageTemp == "Return"){
      Serial.println();
      client.publish("iot/remote/result", messageTemp.c_str());
      bleKeyboard.write(KEY_RETURN);
    }
    else if (messageTemp == "Back"){
      Serial.println();
      client.publish("iot/remote/result", messageTemp.c_str());
      bleKeyboard.write(KEY_ESC);
    }

    else{
      Serial.println();
      Serial.print("Not recognised");
      client.publish("iot/remote/result", messageTemp.c_str());
      Serial.println();
    }
  }
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
      client.subscribe("iot/remote/control");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

platformio.ini

[env:firebeetle32]
platform = espressif32
board = firebeetle32
framework = arduino
monitor_speed = 115200
lib_deps =
knolleary/PubSubClient@^2.8
t-vk/ESP32 BLE Keyboard@^0.3.2

So it’s now as simple as sending the relevant command to the MQTT channel. I’m sure there is more efficient ways to do this, but it works for me.

Hope this helps.

1 Like