/samsungctl

Remote control Samsung televisions via a TCP/IP connection

Primary LanguagePythonMIT LicenseMIT

SAMSUNGCTL

BIG NEWS!!!! samsungctl now supports the ever elusive H and J model year (2014 and 2015) TV's

OK so first thing is first. I want to give a special thanks to the people that helped in the bug testing of this version. It has been a bit of a challenge because of the different devices/OS's that samsungctl is running on. In no special order I want to say TY for the help. If I have missed mentioning ya. let me know. That was one really long issue thread. and Github likes to collapse the thing. I could have missed expanding one or 2 of the sections.

  • @eclair4151
  • @fluxdigital
  • @DJPsycho82
  • @sebdbr
  • @Murph24
  • @davidgurr
  • @vitalets
  • @msvinth
  • @dcorsus
  • @xxKeoxx
  • @iAbadia

Onto the library.

samsungctl is a library and a command line tool for remote controlling Samsung televisions via a TCP/IP connection. It currently supports both pre-2014 and 2016+ TVs as well most of the modern Tizen-OS TVs with Ethernet or Wi-Fi connectivity.

UPDATE: This library supports 2016+ TV's running the latest firmware. Samsung has changed it's websocket connection to now use SSL encryption. We have this all sorted out.

If the TV kicks back an error when connecting the program will then try the SSL connection. The SSL connection uses a token based system. What this means is, there will be only one thing you need to do if your TV uses this kind of a connection. You will get a message on the TV to pair a remote. You will need to click on the "Accept" button. You have 30 seconds to do this before the program will error out.

There is a flat text file that is used to store the token between uses of the program. This is so that you will not have to go through the above process each and every time you use the program. This file is going to be different for each user that can be logged into the computer.micro controller.

On NIX systems the file is stored in ~/.samsungctl

On Windows the file is stored in %appdata%\samsungctl

Both of the locations are specific to the profile of the user that is logged in. I placed the file in these locations as to avoid any permissions related issues.

This program IS NOT the same one that is available on the Python Packaging Index (Pypi). I do not have access to that and unfortunatly the original author Ape has been on hiatus for some time. He may no longer be maintaining the library.

So for the time being you will need to clone this repository and install it using the directions below.

More Changes:

Python 2.7+ compatible Better logging Adds additional keycodes (A LOT) The websocket-client library a requirement not an option

Things to come Expanded control and notifications from the TV Automatic discovery of the TV Support for other Samsung devices



Dependencies

  • Python 2.7+
  • websocket-client
  • curses (optional, for the interactive mode)



Installation

python setup.py install

It's possible to use the command line tool without installation:

python -m samsungctl



Command line usage

You can use samsungctl command to send keys to a TV:

samsungctl --host <host> [options] <key> [key ...]

host is the hostname or IP address of the TV. key is a key code, e.g. KEY_VOLDOWN. See Key codes.

There is also an interactive mode (ncurses) for sending the key presses:

samsungctl --host <host> [options] --interactive

Use samsungctl --help for more information about the command line arguments:

usage: samsungctl [-h] [--version] [-v] [-q] [-i] [--host HOST] [--port PORT]
                  [--method METHOD] [--name NAME] [--description DESC]
                  [--id ID] [--token TOKEN] [--timeout TIMEOUT]
                  [--volume VOLUME] [--mute MUTE] [--brightness BRIGHTNESS]
                  [--contrast CONTRAST] [--sharpness SHARPNESS]
                  [--source SOURCE] [--source-label SOURCE_LABEL]
                  [--config-file PATH/FILENAME]
                  [--start-app APP NAME OR ID] [--app-metadata METADATA]
                  [--key-help]
                  [key [key ...]]

Remote control Samsung televisions via TCP/IP connection

positional arguments:
  key                 keys to be sent (e.g. KEY_VOLDOWN)
optional argument description
-h, --help show this help message and exit
--version show program's version number and exit
-v, --verbose increase output verbosity
-q, --quiet suppress non-fatal output
-i, --interactive interactive control
--host HOST TV hostname or IP address
--port PORT TV port number (TCP)
--method METHOD Connection method (legacy or websocket)
--name NAME remote control name
--description DESC remote control description
--id ID remote control id
--token TOKEN Authentication token that is used by 2014-2015 TVs and some 2016-current TVs
--timeout TIMEOUT socket timeout in seconds (0 = no timeout)
--volume VOLUME sets the volume allowed values: 0-100 or -1 to print the volume
--mute MUTE sets the mute. allowed values: on, off, state. state to print the mute state
--brightness BRIGHTNESS sets the brightness allowed values: 0-100 or -1 to print the brightness
--contrast CONTRAST sets the contrast allowed values: 0-100 or -1 to print the contrast
--sharpness SHARPNESS sets the sharpness allowed values: 0-100 or -1 to print the sharpness
--source SOURCE set the source. you can use the TV defined names.. HDMI1, HDMI2, PC, USB... or you can use the programmed label that appears on the OSD.
--source-label SOURCE_LABEL sets the source label that appears on the OSD
--config-file PATH/FILENAME path and filename to configuration file *see below for mor information
--start-app APPLICATION NAME OR ID starts an application
--app-metadata METADATA string of information the application can use when it starts up. And example would be the browser. To have it open directly to a specific URL you would enter: "http\/\/www.some-web-address.com" wrapping the meta data in quotes will reduce the possibility of a command line parser error.
--key-help {OPTIONAL KEYS} prints out key help
samsungctl --host 192.168.0.10 --name myremote KEY_VOLDOWN

To obtain a list of all of the known keys. samsungctl --help-keys

You can also get help on a specific key samsungctl --key-help KEY_16_9

or if you wanted to list more then one key samsungctl --key-help KEY_16_9 KEY_TTX_MIX

The settings can be loaded from a configuration file. The file is searched from

  • $XDG_CONFIG_HOME/samsungctl.conf
  • ~/.config/samsungctl.conf
  • /etc/samsungctl.conf

in this order. A simple default configuration is bundled with the source as

  • samsungctl.conf <samsungctl.conf>

--config-file


This is how the --config-file parameter works. If this is the first time you are using this library on a TV you must specify --method and --host and key code for the command you wish to execute along with this parameter. By doing this is will make all of the necessary config file settings that are needed to be made for your TV. After the library has sent the command to your TV it will then save the file. Any calls there after will only need to have --config-file PATH/FILENAME along with the command you wish to perform for a command line options. All other information will be retrieved from the file.



Library usage

samsungctl can also be used as a python package.

    import samsungctl

A context managed remote controller object of class Remote can be constructed using the with statement:

    with samsungctl.Remote(config) as remote:
        # Use the remote object



Config Class


Depreciated The constructor takes a configuration dictionary as a parameter. All configuration items must be specified.

Key Type Description
host string Hostname or IP address of the TV.
port int TCP port number. (Default: 55000)
method string Connection method (legacy or websocket)
name string Name of the remote controller.
description string Remote controller description.
id string Additional remote controller ID.
token string Authentication token
timeout int Timeout in seconds. 0 means no timeout.

I have put into place a class that handlees all of thee configuration information. It makes it easier for saving and loading confiig data.

import samsungctl


config = samsungctl.Config(
    name='samsungctl',
    description='samsungctl-library',
    method='websocket',
    port=8001
)

The constrictor for the Config class takes these parameters

Param Name Default value Use
name None Name of the "remote" this is the name that is going to appear on the TV
description None Only used in the legacy connection (pre 2014 TVs)
host None The ip address of the TV
port None The port to connect to. choices aree 55000 (< 2014), 8080 (2014 & 2015), 8001 & 8002 (>= 2016)
method None The connection method. legacy, websocket or encrypted
id None This is an identifier that you can set. when using the "encrypted" method this should be left out
timeout 0 socket timeout, only used for the legacy method
token None Authentication token that is used for 2014 & 2015 and some 2016+ TV's
device_id None Internal Use
upnp_locations None Future Use

the Config class is also where you set your logging level

import logging
import samsungctl


config = samsungctl.Config(
    name='samsungctl',
    method='websocket',
    host='192.168.1.100'
)

config.log_level = logging.DEBUG

There are 2 nice convenience methods for saving and loading a config file.

import samsungctl

config = samsungctl.Config.load('path/to/save/file')

If you load a file the path is saved so you can simply call save to save any new data. If you constructed the Config class manually you will need to pass a path when calling save. and that path is then saved so any subsequent calls to save will not require you to pass thee path

import samsungctl


config = samsungctl.Config(
    name='samsungctl',
    description='samsungctl-library',
    method='websocket',
    host='192.168.1.100'
)

config.save('path/to/save/file')

when calling save if you pass only a folder path and not a folder/file path the name you passed to the constructor will be useed along with the extension ".config"

You do not need to keep track of the config instance. once it is passed to the Remote constructor it is then stored in that instance.

import samsungctl


config = samsungctl.Config.load('path/to/save/file')
remote = samsungctl.Remote(config)
remote.config.save()

You are still able to pass a dictionary to the Remote constructor as well.

The only parameters you MUST supply is the method and the host. everything else has a default value associated with it.



Power Property


I also added power status along with powering off and on 2014+ TV's

import samsungctl


config = samsungctl.Config.load('path/to/save/file')
remote = samsungctl.Remote(config)
print(remote.power)

# turns the TV on
remote.power = True

print(remote.power)
# turns the TV off
remote.power = False

# toggles the power
remote.power = not remote.power

We do not have the ability to turn on the TV's older then 2014.



Exceptions


When something goes wrong you will receive an exception:

Exception Description
SamsungTVError Samsung TV Exception Base Class.
AccessDenied Connection was denied.
ConnectionClosed Connection was closed.
UnhandledResponse Received unknown response.
NoTVFound Unable to locate a TV.
ConfigError Base class for config exceptions.
ConfigUnknownMethod Unknown connection method.
ConfigParseError Config data is not json formatted or is not a formatted flat file.
ConfigLoadError Config path specified cannot be located.
ConfigSavePathError Config save path is not valid.
ConfigSaveError Error saving config.
ConfigSavePathNotSpecified Config save path was not specified.
ConfigParameterError Parameter is not a config parameter.



Example program


This simple program opens and closes the menu a few times.

import samsungctl
import time

config = samsungctl.Config(
    name='samsungctl',
    method='legacy',
    host='192.168.1.100'
)

with samsungctl.Remote(config) as remote:
    for i in range(10):
        remote.control("KEY_MENU")
        time.sleep(0.5)



Mouse Control


Mouse control can only be done by using samsungctl as a python module. Mouse command are built. this way you can accomplish multiple movements in a single "command" and the movement set can be stored for later use. depending on how long it takes to accomplish a movement (distance traveled) you will need to insert a wait period in between each movement.

import samsungctl

config = samsungctl.Config(
    name='samsungctl',
    method='websocket',
    host='192.168.1.100'
)

with samsungctl.Remote(config) as remote:
    mouse = remote.mouse
    mouse.move(x=100, y=300)
    mouse.wait(0.5)
    mouse.left_click()
    mouse.run()
    mouse.clear()

I designed this to all be thread safe. so only one mouse command set can be run at a single time. So if you have the mouse running in a thread and you need to stop the movement from another. or you simply want to terminate the program gracefully. you would call mouse.stop()

I will be at a later date adding the wait periods on the mouse movements so it will be done automatically. I do not own one of the TV's so I do not know how long it takes to move the mouse different distances. I also do not know if the time it takes to move the mouse is linear. An example of linear movement would be it takes 1 second to move the mouse 100 pixels so to move it 200 pixels it would take 2 seconds. most devices that have mouse control also have acceleration and a min/max speed which would be non linear movement. An example of non linear is, if it took 1 second to move the mouse 100 pixels, to move it 200 it would take 1.5 seconds. You can run the code below and report the output to me. that will aide in making this all automatic. I need this data form several TV models and years. as Samsung could have changed the mouse speed and acceleration between years/models.

import samsungctl
import time


config = samsungctl.Config(
    name='samsungctl',
    method='websocket',
    host='192.168.1.100'
)

with samsungctl.Remote(config) as remote:
     mouse = remote.mouse

    def move_mouse(_x, _y):
        mouse.move(x=x, y=y)
        start = time.time()
        mouse.run()
        stop = time.time()
        print('x:', x, 'y:', y, 'time:', (stop - start) * 1000)
        mouse.clear()
        mouse.move(x=-x, y=-y)
        mouse.run()
        mouse.clear()

    for x in range(1920):
        move_mouse(x, 0)

        for y in range(1080):
            move_mouse(0, y)
            move_mouse(x, y)



Voice Recognition


If you TV supports voice recognition you have the ability to start and stop the voice recognition service on the TV. this can be done only by using the samsungctl library as a package to an already existing program. example code of how to do this is below.

import samsungctl
import time

config = samsungctl.Config(
    name='samsungctl',
    method='websocket',
    host='192.168.1.100'
)

with samsungctl.Remote(config) as remote:
    remote.start_voice_recognition()
    time.sleep(5.0)
    remote.stop_voice_recognition()



Applications


This is going to be a wee bit long winded. But here goes

below is a sample of how to access the applications on the TV

import samsungctl

config = samsungctl.Config(
    name='samsungctl',
    method='websocket',
    host='192.168.1.100'
)

with samsungctl.Remote(config) as remote:
    for app in remote.applications:
        print('name:', app.name)
        print('=' * 30)
        print('id:', app.app_id)
        print('is running:', app.is_running)
        print('version:', app.version)
        print()

if you want to access a specific application by name or by the app id

import samsungctl

config = samsungctl.Config(
    name='samsungctl',
    method='websocket',
    host='192.168.1.100'
)

with samsungctl.Remote(config) as remote:
    app = remote.get_application('YouTube')
    if app is not None:
        print('name:', app.name)
        print('=' * 30)
        print('id:', app.app_id)
        print('is running:', app.is_running)
        print('version:', app.version)
        print()

these are the available properties for an application

  • is_lock
  • name
  • app_type
  • position
  • app_id
  • launcher_type
  • mbr_index
  • source_type_num
  • icon
  • id
  • mbr_source
  • action_type
  • version
  • is_visible
  • is_running

now here is a little bonus. we can also iterate over an application for any content groups. and then we can iterate over the content group for the available content in that group

import samsungctl

config = samsungctl.Config(
    name='samsungctl',
    method='websocket',
    host='192.168.1.100'
)

with samsungctl.Remote(config) as remote:
    for app in remote.applications:
        print('name:', app.name)
        print('=' * 30)
        for content_group in app:
            print('   ', content_group.title)
            print('   ', '-' * 26)
            for content in content_group:
                print('       ', content.title)

here are the available properties for the content group

  • title

here are the available properties for the content

  • is_playable
  • subtitle
  • app_type
  • title
  • mbr_index
  • live_launcher_type
  • action_play_url
  • service_id
  • launcher_type
  • source_type_num
  • action_type
  • app_id
  • subtitle2
  • display_from
  • display_until
  • mbr_source
  • id
  • subtitle3
  • icon

You can also run an application or a piece of content by calling run() on either an application or on the content.



Key codes

Here is the new list of keycodes that are supported.



Power Keys


Key Description
KEY_POWEROFF PowerOFF
KEY_POWERON PowerOn
KEY_POWER PowerToggle



Input Keys


Key Description
KEY_SOURCE Source
KEY_COMPONENT1 Component1
KEY_COMPONENT2 Component2
KEY_AV1 AV1
KEY_AV2 AV2
KEY_AV3 AV3
KEY_SVIDEO1 SVideo1
KEY_SVIDEO2 SVideo2
KEY_SVIDEO3 SVideo3
KEY_HDMI HDMI
KEY_HDMI1 HDMI1
KEY_HDMI2 HDMI2
KEY_HDMI3 HDMI3
KEY_HDMI4 HDMI4
KEY_FM_RADIO FMRadio
KEY_DVI DVI
KEY_DVR DVR
KEY_TV TV
KEY_ANTENA AnalogTV
KEY_DTV DigitalTV



Number Keys


Key Description
KEY_1 Key1
KEY_2 Key2
KEY_3 Key3
KEY_4 Key4
KEY_5 Key5
KEY_6 Key6
KEY_7 Key7
KEY_8 Key8
KEY_9 Key9
KEY_0 Key0



Misc Keys


Key Description
KEY_PANNEL_CHDOWN 3D
KEY_ANYNET AnyNet+
KEY_ESAVING EnergySaving
KEY_SLEEP SleepTimer
KEY_DTV_SIGNAL DTVSignal



Channel Keys


Key Description
KEY_CHUP ChannelUp
KEY_CHDOWN ChannelDown
KEY_PRECH PreviousChannel
KEY_FAVCH FavoriteChannels
KEY_CH_LIST ChannelList
KEY_AUTO_PROGRAM AutoProgram
KEY_MAGIC_CHANNEL MagicChannel



Volume Keys


Key Description
KEY_VOLUP VolumeUp
KEY_VOLDOWN VolumeDown
KEY_MUTE Mute



Direction Keys


Key Description
KEY_UP NavigationUp
KEY_DOWN NavigationDown
KEY_LEFT NavigationLeft
KEY_RIGHT NavigationRight
KEY_RETURN NavigationReturn/Back
KEY_ENTER NavigationEnter



Media Keys


Key Description
KEY_REWIND Rewind
KEY_STOP Stop
KEY_PLAY Play
KEY_FF FastForward
KEY_REC Record
KEY_PAUSE Pause
KEY_LIVE Live
KEY_QUICK_REPLAY fnKEY_QUICK_REPLAY
KEY_STILL_PICTURE fnKEY_STILL_PICTURE
KEY_INSTANT_REPLAY fnKEY_INSTANT_REPLAY



Picture in Picture


Key Description
KEY_PIP_ONOFF PIPOn/Off
KEY_PIP_SWAP PIPSwap
KEY_PIP_SIZE PIPSize
KEY_PIP_CHUP PIPChannelUp
KEY_PIP_CHDOWN PIPChannelDown
KEY_AUTO_ARC_PIP_SMALL PIPSmall
KEY_AUTO_ARC_PIP_WIDE PIPWide
KEY_AUTO_ARC_PIP_RIGHT_BOTTOM PIPBottomRight
KEY_AUTO_ARC_PIP_SOURCE_CHANGE PIPSourceChange
KEY_PIP_SCAN PIPScan



Modes


Key Description
KEY_VCR_MODE VCRMode
KEY_CATV_MODE CATVMode
KEY_DSS_MODE DSSMode
KEY_TV_MODE TVMode
KEY_DVD_MODE DVDMode
KEY_STB_MODE STBMode
KEY_PCMODE PCMode



Color Keys


Key Description
KEY_GREEN Green
KEY_YELLOW Yellow
KEY_CYAN Cyan
KEY_RED Red



Teletext


Key Description
KEY_TTX_MIX TeletextMix
KEY_TTX_SUBFACE TeletextSubface



AspectRatio


Key Description
KEY_ASPECT AspectRatio
KEY_PICTURE_SIZE PictureSize
KEY_4_3 AspectRatio4:3
KEY_16_9 AspectRatio16:9
KEY_EXT14 AspectRatio3:4(Alt)
KEY_EXT15 AspectRatio16:9(Alt)

Picture Mode


Key Description
KEY_PMODE PictureMode
KEY_PANORAMA PictureModePanorama
KEY_DYNAMIC PictureModeDynamic
KEY_STANDARD PictureModeStandard
KEY_MOVIE1 PictureModeMovie
KEY_GAME PictureModeGame
KEY_CUSTOM PictureModeCustom
KEY_EXT9 PictureModeMovie(Alt)
KEY_EXT10 PictureModeStandard(Alt)



Menus


Key Description
KEY_MENU Menu
KEY_TOPMENU TopMenu
KEY_TOOLS Tools
KEY_HOME Home
KEY_CONTENTS Contents
KEY_GUIDE Guide
KEY_DISC_MENU DiscMenu
KEY_DVR_MENU DVRMenu
KEY_HELP Help



OSD


Key Description
KEY_INFO Info
KEY_CAPTION Caption
KEY_CLOCK_DISPLAY ClockDisplay
KEY_SETUP_CLOCK_TIMER SetupClock
KEY_SUB_TITLE Subtitle



Zoom


Key Description
KEY_ZOOM_MOVE ZoomMove
KEY_ZOOM_IN ZoomIn
KEY_ZOOM_OUT ZoomOut
KEY_ZOOM1 Zoom1
KEY_ZOOM2 Zoom2



Other Keys


Key Description
KEY_WHEEL_LEFT WheelLeft
KEY_WHEEL_RIGHT WheelRight
KEY_ADDDEL Add/Del
KEY_PLUS100 Plus100
KEY_AD AD
KEY_LINK Link
KEY_TURBO Turbo
KEY_CONVERGENCE Convergence
KEY_DEVICE_CONNECT DeviceConnect
KEY_11 Key11
KEY_12 Key12
KEY_FACTORY KeyFactory
KEY_3SPEED Key3SPEED
KEY_RSURF KeyRSURF
KEY_FF_ FF_
KEY_REWIND_ REWIND_
KEY_ANGLE Angle
KEY_RESERVED1 Reserved1
KEY_PROGRAM Program
KEY_BOOKMARK Bookmark
KEY_PRINT Print
KEY_CLEAR Clear
KEY_VCHIP VChip
KEY_REPEAT Repeat
KEY_DOOR Door
KEY_OPEN Open
KEY_DMA DMA
KEY_MTS MTS
KEY_DNIe DNIe
KEY_SRS SRS
KEY_CONVERT_AUDIO_MAINSUB ConvertAudioMain/Sub
KEY_MDC MDC
KEY_SEFFECT SoundEffect
KEY_PERPECT_FOCUS PERPECTFocus
KEY_CALLER_ID CallerID
KEY_SCALE Scale
KEY_MAGIC_BRIGHT MagicBright
KEY_W_LINK WLink
KEY_DTV_LINK DTVLink
KEY_APP_LIST ApplicationList
KEY_BACK_MHP BackMHP
KEY_ALT_MHP AlternateMHP
KEY_DNSe DNSe
KEY_RSS RSS
KEY_ENTERTAINMENT Entertainment
KEY_ID_INPUT IDInput
KEY_ID_SETUP IDSetup
KEY_ANYVIEW AnyView
KEY_MS MS
KEY_MORE
KEY_MIC
KEY_NINE_SEPERATE
KEY_AUTO_FORMAT AutoFormat
KEY_DNET DNET



Auto Arc Keys


Key Description
KEY_AUTO_ARC_C_FORCE_AGING
KEY_AUTO_ARC_CAPTION_ENG
KEY_AUTO_ARC_USBJACK_INSPECT
KEY_AUTO_ARC_RESET
KEY_AUTO_ARC_LNA_ON
KEY_AUTO_ARC_LNA_OFF
KEY_AUTO_ARC_ANYNET_MODE_OK
KEY_AUTO_ARC_ANYNET_AUTO_START
KEY_AUTO_ARC_CAPTION_ON
KEY_AUTO_ARC_CAPTION_OFF
KEY_AUTO_ARC_PIP_DOUBLE
KEY_AUTO_ARC_PIP_LARGE
KEY_AUTO_ARC_PIP_LEFT_TOP
KEY_AUTO_ARC_PIP_RIGHT_TOP
KEY_AUTO_ARC_PIP_LEFT_BOTTOM
KEY_AUTO_ARC_PIP_CH_CHANGE
KEY_AUTO_ARC_AUTOCOLOR_SUCCESS
KEY_AUTO_ARC_AUTOCOLOR_FAIL
KEY_AUTO_ARC_JACK_IDENT
KEY_AUTO_ARC_CAPTION_KOR
KEY_AUTO_ARC_ANTENNA_AIR
KEY_AUTO_ARC_ANTENNA_CABLE
KEY_AUTO_ARC_ANTENNA_SATELLITE



Panel Keys


Key Description
KEY_PANNEL_POWER
KEY_PANNEL_CHUP
KEY_PANNEL_VOLUP
KEY_PANNEL_VOLDOW
KEY_PANNEL_ENTER
KEY_PANNEL_MENU
KEY_PANNEL_SOURCE
KEY_PANNEL_ENTER



Extended Keys


Key Description
KEY_EXT1
KEY_EXT2
KEY_EXT3
KEY_EXT4
KEY_EXT5
KEY_EXT6
KEY_EXT7
KEY_EXT8
KEY_EXT11
KEY_EXT12
KEY_EXT13
KEY_EXT16
KEY_EXT17
KEY_EXT18
KEY_EXT19
KEY_EXT20
KEY_EXT21
KEY_EXT22
KEY_EXT23
KEY_EXT24
KEY_EXT25
KEY_EXT26
KEY_EXT27
KEY_EXT28
KEY_EXT29
KEY_EXT30
KEY_EXT31
KEY_EXT32
KEY_EXT33
KEY_EXT34
KEY_EXT35
KEY_EXT36
KEY_EXT37
KEY_EXT38
KEY_EXT39
KEY_EXT40
KEY_EXT41

Please note that some codes are different on the 2016+ TVs. For example, KEY_POWEROFF is KEY_POWER on the newer TVs.

I also added all of th keys as methods. so you havee the choice of using the method for sending a key

import samsungctl

config = samsungctl.Config(
    name='samsungctl',
    method='websocket',
    host='192.168.1.100'
)

with samsungctl.Remote(config) as remote:
    remote.command("KEY_VOLUP")

or you can also use this

import samsungctl

config = samsungctl.Config(
    name='samsungctl',
    method='websocket',
    host='192.168.1.100'
)

with samsungctl.Remote(config) as remote:
    remote.KEY_VOLUP()



References

I did not reverse engineer the control protocol myself and samsungctl is not the only implementation. Here is the list of things that inspired samsungctl.