Index of /utilities/unix/tv

      Name                    Last modified      Size  Description
Parent Directory - tv.pl 2017-10-08 18:04 26K
tv.pl
=====

tv.pl is written to control the Sharp LC-70UD27U TV.

It can probably control most modern Sharp TVs to some extent or
another, though it'll need work.


Help!
-----

There are some commands in this protocol that are as yet unexplained,
in particular:

   RSPW ACHA CHWB GSEL KLCC RMDL DX2U SCPV

See notes below for more details. Can you work out what they do? Let
me know on this reddit thread:

   http://www.reddit.com/r/ReverseEngineering/comments/2q6zff/sharp_lc70ud27u_tv_remote_control_protocol_has/

...or e-mail me at <ian@hixie.ch>.


Documentation
-------------

The Sharp LC-70UD27U TV's TCP control protocol is documented in the
LC60_70UD27U_OM.pdf file, page 94 (labeled 7-3). I found a copy of
this file here:

   http://www.ssap.com/snRefMaterialDisplay.aspx?ID=rmljkAKv3H8%3d

Some sleuthing around found similar documentation for other TVs:

   http://elitelcdtv.com/_pdf/Elite-RS232-IP%20Control.pdf


The protocol
------------

The documentation above is not the most... clear.

It describes the general form for commands: four characters to specify
the command, and four characters to specify the arguments. Commands
are terminated by 0x0D bytes. No encoding is specified, but for the
sake of simplicity we'll assume UTF-8.

   [CMND][ARGS][0x0D]

The arguments are typically numeric, left-aligned, padded with spaces
on the right. For example:

   [VOLM][50   ][0x0d]

Or to put it in C-like terms:

   "VOLM50  \r"

According to the documentation, some commands accept the argument "?"
or "????" to find out the current state. It doesn't say which. By
brute force I found those that responded to "?" (I haven't tested for
commands that support "????" but not "?"; spot testing suggests that
they are treated as synonyms).

In practice, I found at least one command where the arguments are just
an arbitray-length string (at least 4 characters long), and as far as
I can tell the encoding is really ASCII, not UTF-8; and bytes with the
high bit set get ignored. I haven't studied this very carefully.

The TV is supposed to respond with some data or "OK" or "ERR" followed
by a 0x0D byte, but in practice some commands respond with multiple
lines (separated by 0x0D), and, more importantly, some commands in
some situations will just hang.

The existence of the following commands is documented, and although
many don't act exactly as documented, or have super-vague
documentation, they are relatively straight-forward:

   Command: POWR
   Arguments: numeric: 0 or 1; or ?
   Turn the TV on or off, in theory.
         0 = turns the TV off
         1 = supposedly, turn the TV on; it only seems to work if
             "quickstart" is enabled in the settings (menu > setup >
             quick start mode > on), in which case the TV is basically
             already on anyway
         ? = returns 1 if the TV is on, 0 if the TV is off with
             "quickstart" enabled.
   If the TV is off with "Quickstart" on, then every command except
   POWR will return ERR. If the TV is off with "Quickstart" off, then
   connections won't even be accepted, so "POWR1   " won't work.

   Command: ITGD
   Arguments: ignored
   Switch to next enabled input.

   Command: ITVD
   Arguments: ignored
   Switch to the last selected TV channel.

   Command: IAVD
   Arguments: numeric: 1..5; or ?
   Select an input:
         1 = HDMI1
         2 = HDMI2
         3 = HDMI3
         4 = HDMI4
         5 = Component or Composite
         ? = returns current input, 1..5

   Command: AVMD
   Arguments: numeric: 0..7, 17; or ?
   Switch to a different AV mode:
         0 = switch to next AV mode
         1 = switch to AV mode "STANDARD"
         2 = switch to AV mode "MOVIE"
         3 = switch to AV mode "GAME"
         4 = switch to AV mode "USER"
         5 = switch to AV mode "DYNAMIC(Fixed)"
         6 = switch to AV mode "DYNAMIC"
         7 = switch to AV mode "PC"
        17 = switch to AV mode "MOVIE THX"
         ? = returns current AV mode, 1..7, 17

   Command: VOLM
   Arguments: numeric: 0..100; or ?
   Set the volume:
    0..100 = set the volume to that value
         ? = return the current volume, 0..100

   Command: HPOS
   Arguments: numeric: -8..8; or ?
   Position the picture:
     -8..8 = set the horizontal position of the picture
         ? = return the current horizontal position
   If the picture can't be positioned (e.g. HDMI), then only 0 is
   accepted as input.

   Command: VPOS
   Arguments: numeric: -8..8; or ?
   Position the picture:
     -8..8 = set the vertical position of the picture
         ? = return the current vertical position
   If the picture can't be positioned (e.g. HDMI), then only 0 is
   accepted as input.

   Command: WIDE
   Arguments: numeric 0..4 or 9, or ?
   Select picture mode:
         0 = switch to next mode
         1 = 4:3
         2 = side-stretch
         3 = zoom
         4 = stretch
         9 = 16:9
         ? = return the current picture mode, 1..4 or 9
   Exactly which arguments work depends on the current input. The
   values above were tested with HDMI and Composite/Component input
   types. The documentation gives different argument values for other
   inputs (5..8 for "PC" (meaning maybe the AV mode?), and 10 and 11
   for the internal modes like USB), which I haven't tested.

   Command: MUTE
   Arguments: numeric 0..2, or ?
   Set the mute mode:
         0 = toggle mute state
         1 = enable mute state
         2 = disable mute state
         ? = return the mute state, 1 or 2

   Command: ACSU
   Arguments: numeric: 0..7; or ?
   Select the surround sound mode:
         0 = switch to next surround sound mode
         1 = switch to Normal mode
         2 = switch to Off mode
         4 = switch to 3D Hall mode
         5 = switch to 3D Movie mode
         6 = switch to 3D Standard mode
         7 = switch to 3D Stadium mode
         ? = return the surround sound mode, 1..6

   Command: OFTM
   Arguments: numeric: 0..4; or ?
   Set the sleep timeout:
         0 = disable the sleep timeout
         1 = set the sleep timeout to 30 minutes
         2 = set the sleep timeout to 60 minutes
         3 = set the sleep timeout to 90 minutes
         4 = set the sleep timeout to 120 minutes
         ? = return 0 if the timeout is disabled, otherwise return the
             number of minutes remaining on the sleep timeout, 1..120

   Command: TVNM
   Arguments: must be 1
   Return the TV's name, as configured in the settings.

   Command: MNRD
   Arguments: must be 1
   Return "UD27U", supposedly the TV's model.

   Command: SWVN
   Arguments: must be 1
   Return "114U1411181", supposedly some software version number.

The following commands are documented but confusing or just not very
well tested by me (I don't have a way to receive TV channels, so the
channel-related ones are hard for me to test):

   Command: RSPW
   Arguments: numeric: 0..2
   Documented as "Power on command setting", with:
         0 = the power command is rejected
         1 = the power on command is accepted (RS-232C)
         2 = the power on command is accepted (IP)
   I've no idea what this actually does. It certainly doesn't seem to
   stop the POWR command from working.

   Command: ACHA
   Arguments: ignored unless it starts with "?" or has more than four
   characters
   Documented as "audio selection toggle", but I've _no_ idea what it
   actually does. It responds with "ERR" if the arguments starts with
   "?" or has more than four characters.

   Command: DCCH
   Arguments: numeric: 2..69 for air or 1..135 for cable; or ?
   This is supposed to change the channel to an analog channel. It
   hangs if the TV has TV channels disabled. "?" returns the current
   value or ERR if the TV isn't tuned to an analog channel.

   Command: DA2P
   Arguments: numeric: 0100..9999; or ?
   This is supposed to change the channel to a digital air channel of
   the form ##.##. It hangs if the TV has TV channels disabled. "?"
   returns the current value or ERR if the TV isn't tuned to a ##.##
   digital channel. In my testing I can't get it to pay any attention
   to the last two digit.

   Command: DC2U
   Arguments: numeric: 1..999; or ?
   This is supposed to change the channel to a digital air channel of
   the form ###.###, giving the first three digits. It hangs if the TV
   has TV channels disabled. "?" returns the current value or ERR if
   the TV isn't tuned to a ###.### digital channel.

   Command: DC2L
   Arguments: numeric: 0..999; or ?
   This is supposed to change the channel to a digital air channel of
   the form ###.###, giving the last three digits. It hangs if the TV
   has TV channels disabled. "?" returns the current value or ERR if
   the TV isn't tuned to a ###.### digital channel. In my testing I
   can't get it to pay any attention to the last two digits. Call this
   after DC2U, not before.

   Command: DC10
   Arguments: numeric: 0..9999; or ?
   This is supposed to change the channel to a digital air channel of
   the form 0####, with the argument giving the last four digits. In
   my testing this never works.

   Command: DC11
   Arguments: numeric: 0..6383; or ?
   This is supposed to change the channel to a digital air channel of
   the form 1####, with the argument giving the last four digits. In
   my testing this never works.

   Command: CHUP
   Arguments: ignored
   This is supposed to change the channel as if the channel-up button
   on the remote was pressed. It hangs if the TV has TV channels
   disabled.

   Command: CHDW
   Arguments: ignored
   This is supposed to change the channel as if the channel-down
   button on the remote was pressed. It hangs if the TV has TV
   channels disabled.

   Command: CLCP
   Arguments: supposedly ignored
   This is supposed to toggle closed captions, but I've not been able
   to test it.

   Command: IPPV
   Arguments: must be 1
   Return "0100" followed by two 0x0D bytes instead of just one. It's
   documented as "the currently supported version of IP protocol is
   displayed" but it's not clear what this means.

   Command: RCKY
   Arguments: numeric: 0..61
   Press a key on the remote control. The values are:
         0 = 0
         1 = 1
         2 = 2
         3 = 3
         4 = 4
         5 = 5
         6 = 6
         7 = 7
         8 = 8
         9 = 9
        10 = .
        11 = ent
        12 = power
        13 = display
        14 = power-source
        15 = rw
        16 = play
        17 = ff
        18 = pause
        19 = prev
        20 = stop
        21 = next
        22 = rec
        23 = option
        24 = sleep
        25 = rec-stop
        26 = power-saving
        27 = cc
        28 = av-mode
        29 = view-mode
        30 = flashback
        31 = mute
        32 = vol-
        33 = vol+
        34 = chup
        35 = chdw
        36 = input
        37 = 37
        38 = menu
        39 = smart-central
        40 = enter
        41 = up
        42 = down
        43 = left
        44 = right
        45 = return
        46 = exit
        47 = ch
        48 = 48
        49 = 49
        50 = a
        51 = b
        52 = c
        53 = d
        54 = freeze
        55 = app1
        56 = app2
        57 = app3
        58 = 2d/3d
        59 = netflix
        60 = aal
        61 = manual
   Some of these values are from the second source mentioned above,
   the rest from the official documentation.

Since the TV returns "ERR" for commands it doesn't know, I brute-
forced the command space to find if there were any other commands that
might be undocumented. I tried all four-character combinations of A..Z
and 0..9, and I tried them with the arguments "1", "2", and "?". (I
haven't tried lowercase a-z, and I haven't tried commands that aren't
four letters long followed by one of those three arguments followed by
three spaces). Here are the commands I found:

   Command: KLCD
   Arguments: A string with four or more characters, ASCII
   Show the string in the bottom right corner of the screen.

   Command: IDIN
   Arguments: numeric: 0..4, 11..15, 50..53, 81, 82; or ?
   Switch the input:
         0 = cable analog (1)
         1 = air analog (1)
         2 = cable digital (3)
         3 = air digital (3)
         4 = cable analog (3)
    11, 50 = HDMI1 (50)
    12, 51 = HDMI2 (51)
    13, 52 = HDMI3 (52)
    14, 53 = HDMI4 (53)
        15 = component (11)
        81 = Home Network (11)
        82 = SD/USB (11)
         ? = returns the number in parentheses corresponding to the
             current selected entry from the list above, or ERR of
             actively switching or if there's no corresponding entry
             in the list above
   The HDMI inputs return ERR if you're already on that channel.
   The behaviour of values 0..4 aren't entirely clear to me.

   Command: RDIN
   Arguments: ignored so long as it's numeric in the range 0..9999
   Return a value based on the current input, as follows:
     HDMI1 returns "5000"
     HDMI2 returns "5100"
     HDMI3 returns "5200"
     HDMI4 returns "5300"
     Component and Composite return "1100"
     Analog TV return "0100"
     Digital TV with channel in the form ##.## returns "0300"
     Digital TV with channel in the form ###.### returns "0400"
     Mircast, Bluetooth, Manual screens return "-100"
     If the input is actively switching, returns "ERR"
   If the Home Network or USB/SD screens are showing, the value
   returned is whatever the value for the previous screen was.
   Notice that the values here are similar to the "IDIN?" values.

   Command: INP5
   Arguments: numeric: 0..2; or ?
   Select a specific input for the shared Component/Composite input:
         0 = probably "autoselect"
         1 = probably "composite"
         2 = "component"
         ? = returns the current setting, 0..2

   Command: DMSL
   Arguments: numeric: 0 or 1; ?
   Show or hide a pointless overlay:
         0 = hides the demo overlay
         1 = shows the demo overlay
         ? = returns the current setting, 0 or 1
   The overlay claims to show the value of upscaling on a 4K display,
   or something, but doesn't seem to actually do so.

   Command: CHWB
   Arguments: unclear
   This seems to be an incomplete "TV+Web" split-screen mode. I
   haven't tested this much since when I enable it it often crashed
   the TV and on at least one occasion I've had to hard-reboot the
   device.

   Command: GSEL
   Arguments: four characters
   Return a multiline string built as follows. A first line based on
   the fourth character of the argument:
         0 = "Avpos: DYNAMIC"
         1 = "Avpos: STANDARD"
         2 = "Avpos: MOVIE"
         3 = "Avpos: DYNAMIC-HD"
         4 = "Avpos: STANDARD-HD"
         5 = "Avpos: MOVIE-HD"
         6 = "Avpos: STANDARD-3D"
         7 = "Avpos: PURE"
      else = "ERR:Arg3"
   ...then if it wasn't "ERR:Arg3", a second line based on the third
   characters of the argument:
         0 = "CTEMP: OFF"
         1 = "CTEMP: HI"
         2 = "CTEMP: HI-MID"
         3 = "CTEMP: MID"
         4 = "CTEMP: MID-LO"
         5 = "CTEMP: LO"
      else = "ERR:Arg2"
   ...then if it wasn't "ERR:Arg2", a third line based on the third
   characters of the argument:
         0 = "WB: OFF"
         1 = "WB: ON"
      else = "ERR:Arg1"
   ...then if it wasn't "ERR:Arg2", a final line "OK". The lines are
   separated by 0x0D bytes. The first character of the argument is
   ignored. I haven't the first clue what this is supposed to do.

   Command: KLCC
   Arguments: numeric?
   No idea what this does.

   Command: RMDL
   Arguments: numeric?
   Return "4". No idea what that means.

   Command: DX2U
   Arguments: numeric: 0..999?
   No idea what this does.

   Command: SCPV
   Arguments: ?
   My notes say I once got this to return "3.0", but I can't reproduce it.


The Script
----------

The tv.pl script assumes that the TV can be resolved in DNS as "tv",
and that it's configured to use port 10002. It then reads "tv.cfg" and
uses the first line as the username and the second line as the
password.

You control the TV by giving command line arguments.

Run "tv.pl help" for details.