Forum Discussion

Editortab's avatar
Editortab
Newbie
3 months ago

Remote control a Roku TV from another location?

Is there any way to control a Roku TV from another location? My mother in law is developing Alzheimer’s and is having problems using the tv. 

3 Replies

  • packetrat's avatar
    packetrat
    Streaming Star

    I don't know of a way to take remote screenshots of the display (maybe there's a developer mode trick?), but you can at least send remote-control keypresses and certain other commands via the ECP API, which listens for HTTP POST requests on TCP port 8060.  It must first be turned on, via

     Settings -> System -> Advanced system settings -> Control by mobile apps -> Enabled (NOT "Limited")

    Also, commands normally must come from a device on the TV's local network, so you need some way to acess your MIL's LAN, such as a Raspberry Pi plugged in there and hosting a VPN endpoint, or maybe a VPN terminated directly to her router if it supports that. I wouldn't recommend port-forwarding to 8060 directly from a public IP, since the protocol isn't meant to be exposed like this, and it would open the door to others messing with her television.

    Edit to add: You might want to also turn on Settings -> System -> Power -> Fast TV Start, so that the television maintains its Wifi or Ethernet connection even when "off", allowing it to also be powered on remotely.  Otherwise, your MIL would need to hit the power button herself before you could get in to do anything.  This does come at the cost of increased power consumption - about 12 watts 24/7, if I remember right, which would be 8.6 kWh/month.

    Here's a simple command-line based shell script I use to control local Roku TVs from an ssh session to the router. Probably not the sort of interface you'd care for, but it might give you some ideas.

    #!/bin/bash
    
    N=`basename $0`
    LASTCH=/tmp/roku-lastch-$N
    SETCH=/tmp/roku-setch-$N
    
    case "$N" in
    dentv|den|dtv)
     I=10.2.1.132
     ;;
    kitchentv|kitchen|ktv)
     I=10.2.1.133
     ;;
    bedroomtv|bedroom|brtv)
     I=10.2.1.129
     ;;
    *)
     echo "invalid basename: $N"
     exit
     ;;
    esac
    
    if [[ "$1" = "" ]]; then
     runtime $N
     exit
    elif
     [[ "$1" = "$" ]]; then
      S="$2"
      c=0
      while [[ $c -lt ${#S} ]]; do
       curl -d '' http://${I}:8060/keypress/Lit_${S:$c:1}
       c=$[ $c + 1 ];
       sleep 0.1
      done
      exit
    fi
    
    FIRST=1
    for k in $*; do
     if [[ $FIRST != 1 ]]; then sleep 0.2; fi
     FIRST=0
     case "$k" in
     off|on|power)
      curl -d '' http://${I}:8060/keypress/Power
      ;;
     mute)
      curl -d '' http://${I}:8060/keypress/VolumeMute
      ;;
     vol-|v-)
      curl -d '' http://${I}:8060/keypress/VolumeDown
      ;;
     vol+|v+|+)
      curl -d '' http://${I}:8060/keypress/VolumeUp
      ;;
     tuner|local|locals|tv|ota)
      curl -d '' http://${I}:8060/keypress/InputTuner
      ;;
     hdmi1|h1)
      curl -d '' http://${I}:8060/keypress/InputHDMI1
      ;;
     hdmi2|h2)
      curl -d '' http://${I}:8060/keypress/InputHDMI2
      ;;
     hdmi3|h3)
      curl -d '' http://${I}:8060/keypress/InputHDMI3
      ;;
     hdmi4|h4)
      curl -d '' http://${I}:8060/keypress/InputHDMI4
      ;;
     ch-)
      curl -d '' http://${I}:8060/keypress/ChannelDown
      ;;
     ch+)
      curl -d '' http://${I}:8060/keypress/ChannelUp
      ;;
     home)
      curl -d '' http://${I}:8060/keypress/Home
      ;;
     back|b)
      curl -d '' http://${I}:8060/keypress/Back
      ;;
     select|ok|sel|s|e)
      curl -d '' http://${I}:8060/keypress/Select
      ;;
     enter)
      curl -d '' http://${I}:8060/keypress/Enter
      ;;
     left|l)
      curl -d '' http://${I}:8060/keypress/Left
      ;;
     right|r)
      curl -d '' http://${I}:8060/keypress/Right
      ;;
     up|u)
      curl -d '' http://${I}:8060/keypress/Up
      ;;
     down|d)
      curl -d '' http://${I}:8060/keypress/Down
      ;;
     replay)
      curl -d '' http://${I}:8060/keypress/InstantReplay
      ;;
     play|pause)
      curl -d '' http://${I}:8060/keypress/Play
      ;;
     rev|rew|rewind|rr)
      curl -d '' http://${I}:8060/keypress/Rev
      ;;
     fwd|ff)
      curl -d '' http://${I}:8060/keypress/Fwd
      ;;
     info|menu|star|a|i)
      curl -d '' http://${I}:8060/keypress/Info
      ;;
     search)
      curl -d '' http://${I}:8060/keypress/Search
      ;;
     backspace|bs)
      curl -d '' http://${I}:8060/keypress/Backspace
      ;;
     findremote|find)
      curl -d '' http://${I}:8060/keypress/FindRemote
      ;;
     launch)
      curl -d '' http://${I}:8060/launch/$2
      exit
      ;;
     netflix)
      curl -d '' http://${I}:8060/launch/12
      ;;
     amazon|prime)
      curl -d '' http://${I}:8060/launch/13
      ;;
     nasa|nasatv)
      curl -d '' http://${I}:8060/launch/244655
      ;;
     media|mediaplayer|mpl)
      curl -d '' http://${I}:8060/launch/2213
      ;;
     sling|slingtv)
      if [[ $# = 2 ]]; then
       R="$2"
       curl -d '' "http://${I}:8060/launch/46041?contentId=${R}&mediaType=live"
       exit
      else
       curl -d '' http://${I}:8060/launch/46041
      fi
      ;;
     yt|youtube)
      if [[ $# = 2 ]]; then
       R="$2"
       if [[ ${R:0:4} == "http" ]]; then
        V="`echo $R | sed 's/.*v=//; s/&.*//'`"
       else
        V="$R"
       fi
       curl -d '' "http://${I}:8060/launch/837?contentId=${V}&mediaType=live"
       exit
      else
       curl -d '' http://${I}:8060/launch/837
      fi
      ;;
     apps)
      lynx -dump http://${I}:8060/query/apps
      ;;
     active-app)
      lynx -dump http://${I}:8060/query/active-app
      ;;
     tv-channels)
      lynx -dump http://${I}:8060/query/tv-channels
      ;;
     tv-active-channel)
      lynx -dump http://${I}:8060/query/tv-active-channel
      ;;
     *)
      if [[ $k =~ ^[0-9.-]+$ && $# = 1 ]]; then
       if [[ "$k" = "-" ]]; then
        if [[ -f $LASTCH && -f $SETCH ]]; then
         C=`cat $LASTCH`
         mv -f $SETCH $LASTCH 2>/dev/null
        else
         echo "No previous channel set."
         exit
        fi
       else
        mv -f $SETCH $LASTCH 2>/dev/null
        C="$k"
       fi
       echo $C >$SETCH
       if [[ "${C:1:1}" != "." && "${C:2:1}" != "." ]]; then C=${C}.1; fi
       echo "channel: $C"
       if [[ ${#C} -lt 4 ]]; then C=0$C; fi
       L=$[ ${#C} - 1 ]
       for d in `seq 0 $L`; do
        curl -d '' http://${I}:8060/keypress/Lit_${C:$d:1}
        sleep 0.1
       done
      else
       echo "literal $k"
       curl -d '' http://${I}:8060/keypress/Lit_$k
      fi
      ;;
     esac
    done

     

  • packetrat's avatar
    packetrat
    Streaming Star

    Hmm, a few minutes ago I made a longish post here explaining how to do this using ECP protocol, including a code sample (just a bash shell script) and discussion of security considerations, but the reply seemingly vanished!

    Did a moderator delete it?  If so, why?

    I did label the script as Python code because Unix shells (Bourne/bash etc.) were not amongst the options, and that seemed closest. Figured that question was purely for syntax highlighting & such.