Pylips is a Python tool to control Philips TVs (2016+) through their reverse-engineered API.
There are some similar modules available, but they lack documentation, miss some API methods and sometimes have outdated code. This module is the most complete one in terms of both functionality and documentation. It supports both Android and non-Android Philips TVs.
It is also the only module that allows toggling 'Ambilight + Hue' setting.
The current version of the API does not allow switching input sources anymore (?), use this tool instead (Android TVs only).
- Prerequisites
- Pairing with the TV (Android TVs only)
- Controlling the TV
- API reference
- Change log
- TO-DO
- Acknowledgements
- Contact details
Provided that you have python (version 3+) on your system, install all the dependencies first:
pip install -r requirements.txt
You may have to use pip3
and python3
instead of pip
and python
depending on how these tools are installed on your system.
If your TV has Android, you have to pair with the TV first to get a username/password which you will need to provide with --user
and --pass
parameters for all future calls.
If your TV does not have Android, you do NOT need to pair with the TV. You should also NEVER use --user
and --pass
parameters - they are required for Android TVs only.
To use this tool with your Philips Android TV you will need a username and a password, which you can get by running the tool with a -- host
parameter (your TV's ip address):
python pylips.py --host 192.168.201.10
The TV will display a 4-digit pin-code that you need to input to get a username and password.
Write down the username and password since they are required for all future calls!
Security note:
To pair with the TV we need to create a HMAC signature using an 88-character (?) key. As far as I can tell the key is used for pairing only. With that in mind and to make this tool as user-friendly as possible, the key is hardcoded. I see no security issues with this but if you are extremely paranoid you can change it: look for a secret_key
in the beginning of the code.
You can take advantage of some of the built-in commands (to be extended) or send your own custom commands.
Add --verbose 0
to any command if you don't want to see the feedback in your terminal (useful for command line sensors).
python pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command %command%
Skip the --user
and --pass
parameters if your TV does not have Android.
Available built-in commands:
TV power:
-
powerstate
- Returns the current power state of the TV ('On' or 'Off')TV remote keys:
-
standby
- Sends Standby key -
mute
- Sends Mute key -
volume_up
- Sends VolumeUp key -
volume_down
- Sends VolumeDown key -
channel_up
- Sends ChannelStepUp key -
channel_down
- Sends ChannelStepDown key -
play
- Sends Play key -
pause
- Sends Pause key -
play_pause
- Sends PlayPause key -
stop
- Sends Stop key -
fast_forward
- Sends FastForward key -
rewind
- Sends Rewind key -
next
- Sends Next key -
previous
- Sends Previous key -
cursor_up
- Sends CursorUp key -
cursor_down
- Sends CursorDown key -
cursor_left
- Sends CursorLeft key -
cursor_right
- Sends CursorRight key -
confirm
- Sends Confirm key -
back
- Sends Back key -
home
- Sends Home key -
options
- Sends Options key -
info
- Sends Info key -
find
- Sends Find key -
adjust
- Sends Adjust key -
watch_tv
- Sends WatchTV key -
viewmode
- Sends Viewmode key -
teletext
- Sends Teletext key -
subtitle
- Sends Subtitle key -
record
- Sends Record key -
online
- Sends Online key -
source
- Sends Source key -
ambilight_onoff
- Sends AmbilightOnOff key -
red
- Sends RedColour key -
green
- Sends GreenColour key -
yellow
- Sends YellowColour key -
blue
- Sends BlueColour key -
dot
- Sends Dot key -
digit_0
- Sends Digit0 key -
digit_1
- Sends Digit1 key -
digit_2
- Sends Digit2 key -
digit_3
- Sends Digit3 key -
digit_4
- Sends Digit4 key -
digit_5
- Sends Digit5 key -
digit_6
- Sends Digit6 key -
digit_7
- Sends Digit7 key -
digit_8
- Sends Digit8 key -
digit_9
- Sends Digit9 keyTV channels:
-
current_channel
- Returns current channel (if in TV mode) -
set_channel
- Turns a specified channel on. Requires a valid--body
argument, see API reference to get it. -
list_channels
- Returns channel list -
list_favorite
- Returns favorite listAmbilight:
-
ambilight_on
- Turns ambilight on -
ambilight_off
- Turns ambilight off -
ambihue_status
- Returns the current status of 'Ambilight + Hue' -
ambihue_on
- Turns 'Ambilight + Hue' on -
ambihue_off
- Turns 'Ambilight + Hue' off -
ambilight_video_immersive
- Sets Ambilight to 'Follow video' (Immersive) -
ambilight_video_standard
- Sets Ambilight to 'Follow video' (Standard) -
ambilight_video_natural
- Sets Ambilight to 'Follow video' (Natural) -
ambilight_video_vivid
- Sets Ambilight to 'Follow video' (Vivid) -
ambilight_video_game
- Sets Ambilight to 'Follow video' (Game) -
ambilight_video_comfort
- Sets Ambilight to 'Follow video' (Comfort) -
ambilight_video_relax
- Sets Ambilight to 'Follow video' (Relax) -
ambilight_audio_adapt_brightness
- Sets Ambilight to 'Follow audio' (Energy Adaptive Brightness) -
ambilight_audio_adapt_colors
- Sets Ambilight to 'Follow audio' (Energy Adaptive Colors) -
ambilight_audio_vu_meter
- Sets Ambilight to 'Follow audio' (VU Meter) -
ambilight_audio_spectrum
- Sets Ambilight to 'Follow audio' (Spectrum Analyzer) -
ambilight_audio_knight_rider_1
- Sets Ambilight to 'Follow audio' (Knight Rider Clockwise) -
ambilight_audio_knight_rider_2
- Sets Ambilight to 'Follow audio' (Knight Rider Alternating) -
ambilight_audio_flash
- Sets Ambilight to 'Follow audio' (Random Pixel Flash) -
ambilight_audio_strobo
- Sets Ambilight to 'Follow audio' (Stroboscope) -
ambilight_audio_party
- Sets Ambilight to 'Follow audio' (Party) -
ambilight_audio_random
- Sets Ambilight to 'Follow audio' (Random Mode)Other:
-
launch_app
- Launches an app (Android TVs only). Requires a valid--body
argument, see API reference to get it.
Examples of using the built-in commands:
Send Stop key:
python pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command stop
Turn Ambilight on:
python pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command ambilight_on
Launch YouTube:
python pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command launch_app --body '{"id":"com.google.android.apps.youtube.tv.activity.ShellActivity-com.google.android.youtube.tv","order":0,"intent":{"action":"Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=com.google.android.youtube.tv cmp=com.google.android.youtube.tv/com.google.android.apps.youtube.tv.activity.ShellActivity }","component":{"packageName":"com.google.android.youtube.tv","className":"com.google.android.apps.youtube.tv.activity.ShellActivity"}},"label":"YouTube"}'
The tools exposes two general commands to talk to the TV's API: get
(sends GET request and gets back some data like ambilight mode) and post
(sends POST request that posts some data and changes something in the TV - like turning the ambilight off).
Read the API reference first to understand available endpoints and how to use them. There are some unexpected things like:
- Pairing process returns objects like '{"error_id":"SUCCESS"}' (why, Philips?!)
- Using strings like 'On'/'Off' for boolean variables (really, Philips?!)
- API returns 'Nodeid' for some GET requests, while expecting 'nodeid' for POST requests (come on, Philips has to do it all on purpose, right? Right?)
Get method:
To use the get
method you need to provide a path to the required endpoint with a --path
argument. For example, this will send a get request to the system
endpoint (https://yourIP:1926/6/system):
python pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command get --path system
Post method:
To use the post
method you need to provide a path to the required endpoint with a --path
argument and the body of your POST request with a --body
argument. For example, this will send a post request to the menuitems/settings/current
endpoint with a body that will get back the status of 'Ambilight + Hue' (notice that the --body
argument needs to come inside the quotes):
python pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command get --path menuitems/settings/current --body '{"nodes":[{"nodeid":2131230774}]}'
The TV's API is roughly based on JointSpace with a current version of 6.2. The only available official documentation that I was able to find is for JointSpace version 1, which is incredibly outdated.
Since no official API documentation is available, I've decided to collect and document to the best of my knowledge all endpoints that are working in API version 6+ (Philips TVs 2016-2018). This API reference is based on:
- Official JointSpace documentation
- Community endpoints (various endpoints discovered by the community over the years)
- Endpoints discovered by using a man-in-the-middle attack on an iPhone running an official Philips TV remote app (this finally allowed to discover an endpoint responsible for toggling 'Ambilight + Hue' mode among other things)
All endpoints in API reference are tested and fully working unless explicitly marked otherwise. Some channel endpoints are missing since I can not test them until January 2019. Any comments, new endpoints and fixes to the API reference are incredibly welcome.
The API reference (work in progress).
Added
- Expand built-in commands (set/get TV channel and launch apps)
- Add
--verbose
option
Added
- Non-Android Philips TVs are now also supported
Added
- All TV remote key commands are now built-in
- Add change log to README
Initial release
- Finish documenting and testing all available API endpoints (January 2019)
- Increase number of built-in commands
- Improve error handling when sending requests
- User-friendly way of changing Ambilight colors
- Move settings to a config file
- MQTT server support
- Home assistant integration
- TV pairing mechanism as well as the inspiration for this tool come from @suborb's brilliant repo.
- This tool was also inspired by @arzzen's CLI tool.
- @jomwells did a pretty good job of collecting various ambilight endpoints.
- Some good info from @marcelrv.
Email: eslavnov@gmail.com; LinkedIn: https://www.linkedin.com/in/evgeny-slavnov/