UNPKG

node-red-contrib-pylips-philips-tv-control

Version:

This is only a subflow which then calls the python script in pylips. So the rest of the readme is directly copied from there.

117 lines (114 loc) 58.9 kB
{ "id": "d3e3e2834d4439c5", "type": "subflow", "name": "Philips TV (pylips)", "info": "# Node-red\r\nThis is NodeRed wrapper for the Python library [eslavnov/pylips](https://github.com/eslavnov/pylips). \r\nSo thanks to eslavnov's great work basically all there was to do is to copy the description over to here. \r\n\r\nAs for now, you will need to manually clone pylips into your home folder (~). \r\nAlso for me the standart implementation did not work, this is why I forked the original and made some (for now quick an dirty) changes. \r\nMostly I replaced \"https\" by \"http\" and changed everything that was the \"ssl\" port on ealrier models to use the same port as http.\r\n\r\n```\r\ncd ~\r\ngit clone https://github.com/dajuly20/pylips/ #This will give you my changed version (I have a 65PUS7607/12 from 2022)\r\n# - OR -\r\ngit clone https://github.com/eslavnov/pylips #This gives you the original version from https://github.com/eslavnov\r\n```\r\n\r\nBecause you need to authorize you TV and enter it's IP / Hostname you will need to cd into the directory\r\n```\r\ncd pylips\r\nnano settings.ini #At least the IP / Hostname. \r\npython3 pylips.py\r\n```\r\nWhen the authorization was successfull you can now use the node in nodered.\r\n\r\n## UI Remote-control (basic functionality)\r\nThe fist thing I wasted time with is making this UI - Remote, that has the most important buttons\\\r\n![UI Remote](remote.png) \\\r\n\r\n\r\n[UI Remote](examples/ui-remote.json) (To Download klick here)\r\n\r\nNext steps: \r\nPush the changes I made to pylips to the edge and make them parameterized.\r\nWhen there is only one library, the cloning of pylips can become automated (as dependency in package.json)\r\n\r\nThanks @eslavnov for you work! \r\n\r\n\r\n# Pylips\r\nPylips is a Python tool to control Philips TVs (2015+) through their reverse-engineered API. \r\n\r\n1. Supports both Android and non-Android TVs\r\n1. 80+ built-in commands + support for custom \"GET\" and \"POST\" requests to the API\r\n1. All commands work on TVs with API version 6, most of them also work for API version 5\r\n1. Full control of Ambilight including color, brightness, mode and 'Ambilight + Hue'\r\n1. Allows sending TV status updates and receiving commands over MQTT\r\n\r\nThe current version of the API does not allow switching input sources anymore. For Android TVs with Google Assistant, Pylips can switch between any input sources that your TV has. For Android TVs without Google Assistant, see some options [here](#switching-input-sources).\r\n\r\n## Table of contents ##\r\n1. [Prerequisites](#prerequisites)\r\n1. [Setting up Pylips](#setting-up-pylips)\r\n 1. [New users](#new-users)\r\n 1. [Migrating from older versions](#migrating-from-older-versions)\r\n1. [Controlling the TV (manual mode)](#controlling-the-tv-manual-mode)\r\n 1. [Built-in commands](#built-in-commands)\r\n 1. [Custom commands](#custom-commands)\r\n1. [Controlling the TV (MQTT mode)](#controlling-the-tv-mqtt-mode)\r\n1. [Switching input sources](#switching-input-sources)\r\n1. [API reference](#api-reference)\r\n1. [Change log](#change-log)\r\n1. [TO-DO](#to-do)\r\n1. [Acknowledgements](#acknowledgements)\r\n1. [Contact details](#contact-details)\r\n\r\n## Prerequisites\r\n\r\nProvided that you have python (version 3+) on your system, install all the dependencies first:\r\n\r\n```\r\npip3 install -r requirements.txt\r\n```\r\n\r\nYou may have to use `pip` and `python` instead of `pip3` and `python3` depending on how these tools are installed on your system.\r\n\r\n## Setting up Pylips\r\n\r\n### New users ###\r\n\r\nTo begin using Pylips you first need to add the ip adress of your TV to the [TV] section in the `settings.ini` file. If you want to use MQTT, you will also need to fill in the [MQTT] section and set the required flags in the [DEFAULT] section:\r\n```\r\n[DEFAULT]\r\nverbose = True # show various debug output\r\nMQTT_listen = False # listen for MQTT commands. Requires correct [MQTT] settings\r\nMQTT_update = False # publish status updates over MQTT. Requires correct [MQTT] settings\r\nnum_retries = 3 # number of retries when sending requests. No need to change it unless your network sucks.\r\nupdate_interval = 3 # interval between updates in seconds (used if MQTT_update = True). Your TV might not appreciate lower values.\r\n[TV]\r\nhost = # TV's ip address\r\nport = # will be discovered automatically, but you can override it here\r\napiv = # will be discovered automatically, but you can override it here\r\nuser = # will be discovered automatically (if required for your TV model), but you can override it here\r\npass = # will be discovered automatically (if required for your TV model), but you can override it here\r\nprotocol = # will be discovered automatically, but you can override it here\r\nambihue_node = # will be discovered automatically, but you can override it here\r\n[MQTT]\r\nhost = # your MQTT broker's ip address\r\nport = # your MQTT broker's port\r\nuser = # your MQTT username\r\npass = # your MQTT password\r\nTLS = False # use TLS \r\ncert_path = # full path to your custom certificate if you are using one, otherwise leave it blank \r\ntopic_pylips = # Pylips will listen for commands to this topic\r\ntopic_status = # Pylips will send status updates to this topic\r\n```\r\n\r\nNow turn your TV on and run Pylips without any arguments to complete setting it up (it will discover your TV's API version, port and protocol, and will also pair and save the credentials if required):\r\n\r\n`python3 pylips.py`\r\n\r\nOnce it's done, you are ready to use Pylips!\r\n\r\n**Security note:**\r\n\r\nTo pair with the Android TVs 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.\r\n\r\n**Custom config path:**\r\n\r\nYou can load a custom config by specifying its **absolute** path with a `--config` parameter:\r\n\r\n`python pylips.py --config '/home/eslavnov/repos/Pylips/some_settings.ini'`\r\n\r\n## Controlling the TV (manual mode) ##\r\nYou can take advantage of some of the built-in commands or send your own custom commands.\r\n\r\n### Built-in commands ###\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command %command%\r\n```\r\n\r\nAny passed arguments will override the settings in `settings.ini` without overwriting them. If you have already run the discovery for new users, you don't have to specify `--host`, `--user` and `-pass` parameters. Also skip the `--user` and `--pass` parameters if your TV does not have Android. Add `--verbose False` to any command if you don't want to see the feedback in your terminal (useful for command line sensors). \r\n\r\n\r\n**Available built-in commands:**\r\n\r\n&nbsp; &nbsp; &nbsp; &nbsp; **TV status:**\r\n1. `powerstate` - Returns current power state of the TV ('On' or 'Off')\r\n1. `volume` - Returns current volume and mute status\r\n1. `current_channel` - Returns current channel (if in TV mode)\r\n1. `current_app` - Returns current app (Android TVs only)\r\n\r\n **TV input (only for TVs with Google Assistant):**\r\n1. `input_hdmi_1` - Switches TV's input to HDMI 1\r\n1. `input_hdmi_2` - Switches TV's input to HDMI 2\r\n1. `input_hdmi_3` - Switches TV's input to HDMI 3\r\n1. `input_hdmi_4` - Switches TV's input to HDMI 4\r\n\r\n **TV remote keys:**\r\n1. `standby` - Sends Standby key\r\n1. `mute` - Sends Mute key\r\n1. `volume_up` - Sends VolumeUp key\r\n1. `volume_down` - Sends VolumeDown key\r\n1. `channel_up` - Sends ChannelStepUp key\r\n1. `channel_down` - Sends ChannelStepDown key\r\n1. `play` - Sends Play key\r\n1. `pause` - Sends Pause key\r\n1. `play_pause` - Sends PlayPause key\r\n1. `stop` - Sends Stop key\r\n1. `fast_forward` - Sends FastForward key\r\n1. `rewind` - Sends Rewind key\r\n1. `next` - Sends Next key\r\n1. `previous` - Sends Previous key\r\n1. `cursor_up` - Sends CursorUp key\r\n1. `cursor_down` - Sends CursorDown key\r\n1. `cursor_left` - Sends CursorLeft key\r\n1. `cursor_right` - Sends CursorRight key\r\n1. `confirm` - Sends Confirm key\r\n1. `back` - Sends Back key\r\n1. `home` - Sends Home key\r\n1. `options` - Sends Options key\r\n1. `info` - Sends Info key\r\n1. `find` - Sends Find key\r\n1. `adjust` - Sends Adjust key\r\n1. `watch_tv` - Sends WatchTV key\r\n1. `viewmode` - Sends Viewmode key\r\n1. `teletext` - Sends Teletext key\r\n1. `subtitle` - Sends Subtitle key\r\n1. `record` - Sends Record key\r\n1. `online` - Sends Online key\r\n1. `source` - Sends Source key\r\n1. `ambilight_onoff` - Sends AmbilightOnOff key\r\n1. `red` - Sends RedColour key\r\n1. `green` - Sends GreenColour key\r\n1. `yellow` - Sends YellowColour key\r\n1. `blue` - Sends BlueColour key\r\n1. `dot` - Sends Dot key\r\n1. `digit_0` - Sends Digit0 key\r\n1. `digit_1` - Sends Digit1 key\r\n1. `digit_2` - Sends Digit2 key\r\n1. `digit_3` - Sends Digit3 key\r\n1. `digit_4` - Sends Digit4 key\r\n1. `digit_5` - Sends Digit5 key\r\n1. `digit_6` - Sends Digit6 key\r\n1. `digit_7` - Sends Digit7 key\r\n1. `digit_8` - Sends Digit8 key\r\n1. `digit_9` - Sends Digit9 key\r\n\r\n **TV channels:**\r\n1. `set_channel` - Turns a specified channel on. Requires a valid `--body` argument, see the [API reference](docs/Chapters/Activities-TV-(GET).md) to get it.\r\n1. `list_channels` - Returns channel list\r\n1. `list_favorite` - Returns favorite list\r\n\r\n **Ambilight:**\r\n1. `ambilight_on` - Turns ambilight on\r\n1. `ambilight_off` - Turns ambilight off\r\n1. `ambihue_status` - Returns the current status of 'Ambilight + Hue'\r\n1. `ambihue_on` - Turns 'Ambilight + Hue' on\r\n1. `ambihue_off` - Turns 'Ambilight + Hue' off\r\n1. `ambilight_color` - Sets ambilight color (in HSB format). Requires a valid `--body` argument: `{\"hue\": 360, \"saturation\": 100, \"brightness\": 255}`\r\n1. `ambilight_brightness` - Sets ambilight brightness. Requires a valid `--body` argument: `{\"value\": 10}`\r\n1. `ambilight_video_immersive` - Sets Ambilight to 'Follow video' (Immersive)\r\n1. `ambilight_video_standard` - Sets Ambilight to 'Follow video' (Standard)\r\n1. `ambilight_video_natural` - Sets Ambilight to 'Follow video' (Natural)\r\n1. `ambilight_video_vivid` - Sets Ambilight to 'Follow video' (Vivid)\r\n1. `ambilight_video_game` - Sets Ambilight to 'Follow video' (Game)\r\n1. `ambilight_video_comfort` - Sets Ambilight to 'Follow video' (Comfort)\r\n1. `ambilight_video_relax` - Sets Ambilight to 'Follow video' (Relax)\r\n1. `ambilight_color_hot_lava` - Sets Ambilight to 'Follow color' (Hot lava)\r\n1. `ambilight_color_warm_white` - Sets Ambilight to 'Follow color' (Warm white)\r\n1. `ambilight_color_cool_white` - Sets Ambilight to 'Follow color' (Cool white)\r\n1. `ambilight_color_fresh_nature` - Sets Ambilight to 'Follow color' (Fresh nature)\r\n1. `ambilight_deep_water` - Sets Ambilight to 'Follow color' (Deep water)\r\n1. `ambilight_audio_adapt_brightness` - Sets Ambilight to 'Follow audio' (Energy Adaptive Brightness)\r\n1. `ambilight_audio_adapt_colors` - Sets Ambilight to 'Follow audio' (Energy Adaptive Colors)\r\n1. `ambilight_audio_vu_meter` - Sets Ambilight to 'Follow audio' (VU Meter)\r\n1. `ambilight_audio_spectrum` - Sets Ambilight to 'Follow audio' (Spectrum Analyzer)\r\n1. `ambilight_audio_knight_rider_1` - Sets Ambilight to 'Follow audio' (Knight Rider Clockwise)\r\n1. `ambilight_audio_knight_rider_2` - Sets Ambilight to 'Follow audio' (Knight Rider Alternating)\r\n1. `ambilight_audio_flash` - Sets Ambilight to 'Follow audio' (Random Pixel Flash)\r\n1. `ambilight_audio_strobo` - Sets Ambilight to 'Follow audio' (Stroboscope)\r\n1. `ambilight_audio_party` - Sets Ambilight to 'Follow audio' (Party)\r\n1. `ambilight_audio_random` - Sets Ambilight to 'Follow audio' (Random Mode)\r\n\r\n **Other:**\r\n1. `launch_app` - Launches an app (Android TVs only). Requires a valid `--body` argument. See the [API reference](docs/Chapters/Applications-(GET).md) to get a list of installed apps, find your app in this list and use it as a `--body` argument.\r\n1. `power_on` - Turns on the TV even if it's in a deep sleep mode. You might need to run `allow_power_on` first, although it was not needed for me.\r\n1. `allow_power_on` - Allows to remotely power on the TV via chromecast requests.\r\n1. `google_assistant` - Allows to pass requests to Google Assistant if your model supports it. Requires a `--body` argument containing a `query` with the command that you want to pass to Google Assistant. See example below.\r\n\r\n**Examples of using the built-in commands:**\r\n\r\nSend Stop key:\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command stop\r\n```\r\n\r\nTurn Ambilight on:\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command ambilight_on\r\n```\r\n\r\nLaunch YouTube:\r\n```\r\npython3 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\"}'\r\n```\r\n\r\nLaunch Netflix:\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command launch_app --body '{\"label\":\"Netflix\",\"intent\":{\"component\":{\"packageName\":\"com.netflix.ninja\",\"className\":\"com.netflix.ninja.MainActivity\"},\"action\":\"Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=com.netflix.ninja cmp=com.netflix.ninja/.MainActivity }\"},\"order\":0,\"id\":\"com.netflix.ninja.MainActivity-com.netflix.ninja\",\"type\":\"app\"}'\r\n```\r\n\r\nLaunch Amazon Prime Video:\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command launch_app --body '{\"id\":\"com.amazon.amazonvideo.livingroom\",\"order\":0,\"intent\":{\"action\":\"Intent{act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=com.amazon.amazonvideo.livingroom }\",\"component\":{\"packageName\":\"com.amazon.amazonvideo.livingroom\",\"className\":\"com.amazon.ignition.IgnitionActivity\"}},\"label\":\"Prime Video\"}'\r\n```\r\n\r\nLaunch Kodi:\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command launch_app --body '{\"id\":\"org.xbmc.kodi\",\"order\":0,\"intent\":{\"action\":\"Intent{act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=org.xbmc.kodi }\",\"component\":{\"packageName\":\"org.xbmc.kodi\",\"className\":\"org.xbmc.kodi.Splash\"}},\"label\":\"Kodi\"}'\r\n```\r\n\r\nSwitch input to HDMI 1 using a built-in command (requires Google Assistant):\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command input_hdmi_1\r\n```\r\n\r\nSwitch input to any source (for example, SCART) using Google Assistant directly:\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command google_assistant --body '{\"query\":\"SCART\"}'\r\n```\r\n\r\nControl connected lights in your house using Google Assistant:\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command google_assistant --body '{\"query\":\"Turn on lights\"}'\r\n```\r\n\r\n\r\n### Custom commands ###\r\nThe 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). You can also add custom commands to `available_commands.json`.\r\n\r\nRead the API reference first to understand available endpoints and how to use them. There are some unexpected things like:\r\n* Pairing process returns objects like '{\"error_id\":\"SUCCESS\"}' (why, Philips?!)\r\n* Using strings like 'On'/'Off' for boolean variables (really, Philips?!)\r\n* 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?)\r\n\r\n**Get method:**\r\n\r\nTo 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):\r\n\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command get --path system\r\n```\r\n\r\n**Post method:**\r\n\r\nTo 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 for UNIX systems**):\r\n\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command post --path menuitems/settings/current --body '{\"nodes\":[{\"nodeid\":2131230774}]}'\r\n```\r\n\r\n**For Windows systems**:\r\n\r\n```\r\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command post --path menuitems/settings/current --body ^\"{^\"^\"nodes^\"^\":[{^\"^\"nodeid^\"^\":2131230774}]}^\"\r\n```\r\n\r\n## Controlling the TV (MQTT mode) ##\r\nPylips can connect to your MQTT broker to listen for commands and to publish TV status updates.\r\n\r\nEdit the `settings.ini` according to your config and simply run `python3 pylips.py` without any arguments to run in MQTT mode.\r\n\r\nEnabling `MQTT_listen` in `settings.ini` will allow you to send commands to a topic specified in `topic_pylips` by posting a JSON message. This works pretty much the same as sending manual commands: your arguments become keys and their values - values of these keys. You can send any commands (POST, GET and built-in), but you won't get anything in return since you are just publishing a message over MQTT. Useful for POST commands that change the state of your TV, but for general GET requests you are better off using the manual mode.\r\n\r\nSee examples:\r\n\r\n```\r\n# Let's say we want to change the brightness of ambilight to max (10):\r\n\r\n# BUILT-IN COMMANDS\r\n\r\n# Manual mode: \r\npython3 pylips.py --command ambilight_brightness --body '{\"value\":10}'\r\n\r\n# MQTT mode: \r\n{\"command\":\"ambilight_brightness\", \"body\":{\"value\":10}} \r\n\r\n\r\n# POST REQUESTS\r\n\r\n# Manual mode: \r\npython3 pylips.py --command post --path 'menuitems/settings/update' --body '{\"values\":[{\"value\":{\"Nodeid\":2131230769,\"Controllable\":\"true\", \"Available\":\"true\", \"string_id\":\"Brightness\", \"data\":{\"value\":10}}}]}'\r\n\r\n# MQTT mode: \r\n{\"command\":\"post\", \"path\": \"menuitems/settings/update\", \"body\": {\"values\":[{\"value\":{\"Nodeid\":2131230769,\"Controllable\":\"true\", \"Available\":\"true\",\"string_id\":\"Brightness\", \"data\":{\"value\":10}}}]}}\r\n \r\n```\r\n\r\nEnabling `MQTT_update` in `settings.ini` will publish status updates to `topic_status` like these:\r\n```\r\n{\"powerstate\": \"On\", \"volume\": 28, \"muted\": false, \"cur_app\": \"org.droidtv.settings\", \"ambilight\": {\"styleName\": \"FOLLOW_VIDEO\", \"isExpert\": false, \"menuSetting\": \"IMMERSIVE\"}, \"ambihue\": false}\r\n```\r\n```\r\n{\"powerstate\": \"On\", \"volume\": 28, \"muted\": false, \"cur_app\": {\"app\": \"TV\", \"channel\": {\"channel\": {\"ccid\": 644, \"preset\": \"15\", \"name\": \"Comedy Central HD\"}, \"channelList\": {\"id\": \"allcab\", \"version\": \"19\"}}}, \"ambilight\": {\"styleName\": \"OFF\", \"isExpert\": false}, \"ambihue\": false}\r\n```\r\n\r\n## API reference\r\nThe TV's API is roughly based on [JointSpace](http://jointspace.sourceforge.net/) 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. \r\n\r\nSince 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). Most of them should also work for API version 5 (2015 TVs). This API reference is based on:\r\n* [Official JointSpace documentation](http://jointspace.sourceforge.net/projectdata/documentation/jasonApi/1/doc/API.html)\r\n* Community endpoints (various endpoints discovered by the community over the years)\r\n* 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)\r\n\r\nAll endpoints in API reference are tested and fully working unless explicitly marked otherwise. Any comments, new endpoints and fixes to the API reference are incredibly welcome.\r\n\r\n[The API reference](docs/Home.md).\r\n\r\n## Switching input sources\r\nThe current version of the API does not allow switching input sources anymore.\r\nIf your TV has Android, you have several options to switch sources:\r\n1. If your TV supports Google Assistant, you can either use built-in commands in Pylips (`input_hdmi_x`) or use `google_assistant`. In both cases Pylips will send a local request to the Google Assistant running on the TV, which in turn will handle switching the input.\r\n1. For some models sending keys like `F1`, `F2`, etc. allow to switch sources. You can use `adb` to send these key events to your TV or use this [wrapper](https://github.com/eslavnov/android-tv-remote).\r\n1. Using adb you can also switch the sources directly. See the example below, the last digit in `HdmiService%2FHW9` indicates an input source (for me `HdmiService%2FHW9` is HDMI 2 and `HdmiService%2FHW10` is HDMI 1).\r\n```\r\nadb shell am start -a android.intent.action.VIEW -d content://android.media.tv/passthrough/org.droidtv.hdmiService%2F.HdmiService%2FHW9 -n org.droidtv.zapster/.playtv.activity.PlayTvActivity -f 0x10000000\r\n```\r\n\r\n## Change log\r\n\r\n### 1.3.2 - 2021-01-30\r\n**Fixed**\r\n- Pylips now won't crash on older models (API version 1; most of the commands will work but not all)\r\n\r\n### 1.3.1 - 2021-01-17\r\n**Changed**\r\n- API documention moved from the wiki to the repo. Please feel free to send PRs with improvements!\r\n\r\n**Fixed**\r\n- Malformed JSON in MQTT commands is now properly handled\r\n- Improved error handling in API version discovery process\r\n\r\n### 1.3.0 - 2020-12-13\r\n**Added**\r\n- `google_assistant` command to send queries to Google Assistant running on the TV. Check updated examples to see how you can use it.\r\n- `input_hdmi_1`, `input_hdmi_2`, `input_hdmi_3`, `input_hdmi_4` commands to switch input sources (requires Google Assistant).\r\n\r\n**Fixed**\r\n- Improved handling of Ambilight + Hue feature, hopefully it should now work correctly for all models. Thank you all for the provided feedback and especially @Mr-Groch.\r\n- Verbose option is now properly respected in all modes.\r\n\r\n### 1.2.0 - 2020-02-28\r\n**Added**\r\n- `ambilight_color_hot_lava`, `ambilight_color_warm_white`, `ambilight_color_cool_white`, `ambilight_color_fresh_nature`, `ambilight_color_deep_water` commands\r\n\r\n### 1.1.1 - 2020-02-20\r\n**Fixed**\r\n- MQTT payload encoded with utf8 is now correctly decoded. Thx @popy2k14!\r\n\r\n### 1.1.0 - 2020-01-12\r\n**Added**\r\n- Remote `power_on` command that works even from sleep mode. Should work for all Android TVs, not sure about other models. Thx [@neophob](https://github.com/neophob)!\r\n\r\n**Fixed**\r\n- Paths issue when running outside Pylips folder on Windows systems\r\n\r\n**Changed**\r\n- SSL session is now being reused to help with API stoping to respond\r\n- Pycryptodome instead of the outdated pycrypto dependency\r\n\r\n### 1.0.11 - 2019-11-27\r\n**Added**\r\n- Custom settings file support\r\n\r\n### 1.0.10 - 2019-10-27\r\n**Changed**\r\n- Improved response handling in MQTT\r\n\r\n### 1.0.9 - 2019-07-30\r\n**Fixed**\r\n- Fixed a bug in MQTT loop\r\n\r\n### 1.0.8 - 2019-06-11\r\n**Fixed**\r\n- Fixed an edge case when a combination of certain parameters broke the tool (`MQTT_listen = True` + `MQTT_update = False`)\r\n\r\n**Added**\r\n- Add support for custom certificates (MQTT mode)\r\n\r\n### 1.0.7 - 2019-05-22\r\n**Fixed**\r\n- Got my hands on some non-android TVs, fixed some small bugs in pairing/sending commands\r\n\r\n### 1.0.6 - 2019-05-12\r\n**Fixed**\r\n- Fixed `ambilight_brightness` command (manual mode)\r\n\r\n### 1.0.5 - 2019-05-05\r\n**Fixed**\r\n- Fixed `launch_app` command\r\n\r\n### 1.0.4 - 2019-04-29\r\n**Fixed**\r\n- Fixed a broken check for `path` and `body` arguments in MQTT mode\r\n\r\n### 1.0.3 - 2019-04-28\r\n**Fixed**\r\n- Fixed a bug that broke some POST requests\r\n\r\n### 1.0.2 - 2019-04-27\r\n**Changed**\r\n- Relative paths => absolute paths so it plays nice with tools like crontab\r\n\r\n### 1.0.1 - 2019-04-25\r\n**Changed**\r\n- Fixed a bug in pairing (Android TVs)\r\n- Changed `power_on` to `powerstate` in TV status, so now we support \"Standby\" and possibly other modes (MQTT-only)\r\n\r\n### 1.0.0 - 2019-04-21\r\n**Changed**\r\n- Most of the app was rewritten, but it's backward-compatible with previous versions.\r\n- Pylips is now a Python class so you can potentially integrate it with your other projects\r\n\r\n**Added**\r\n- Config file so you don't have to pass the same parameters every time\r\n- Automatic discovery of your TV's API version, port and protocol\r\n- Automatic pairing for Android TVs\r\n- Support for API version 5 + any newer versions should also work (unless Philips breaks something in the future versions of the API)\r\n- MQTT listener: send commands to Pylips over MQTT\r\n- MQTT updater: Pylips can listen for TV status updates and send them over MQTT\r\n- Extend built-in commands (set ambilight color, set ambilight brightness, get current volume, get current app)\r\n- Move built-in commands to a separate JSON file\r\n\r\n### 0.4 - 2019-01-28\r\n**Added**\r\n- Expand built-in commands (set/get TV channel and launch apps)\r\n- Add `--verbose` option\r\n\r\n### 0.3 - 2018-12-31\r\n**Added**\r\n- Non-Android Philips TVs are now also supported\r\n\r\n### 0.2 - 2018-12-30\r\n**Added**\r\n- All TV remote key commands are now built-in\r\n- Add change log to README\r\n\r\n### 0.1 - 2018-12-26\r\nInitial release\r\n\r\n## TO-DO\r\n~1. Finish documenting and testing all available API endpoints (January 2019)~ DONE\r\n\r\n~2. Increase number of built-in commands~ DONE\r\n\r\n~3. Improve error handling when sending requests~ DONE\r\n\r\n~4. User-friendly way of changing Ambilight colors~ DONE\r\n\r\n~5. Move settings to a config file~ DONE\r\n\r\n~6. MQTT server support~ DONE\r\n\r\n~7. Home assistant integration~ CANCELLED: not needed since you can now integrate it with MQTT sensors/switches.\r\n\r\nAt this point I consider the tool to be completed. No new functionality is planned, but I will fix any reported bugs and add any missing API endpoints/commands. [Open an issue](https://github.com/eslavnov/pylips/issues) with your problem/suggestions.\r\n\r\n## Acknowledgements\r\n1. TV pairing mechanism as well as the inspiration for this tool come from [@suborb](https://github.com/suborb)'s brilliant [repo](https://github.com/suborb/philips_android_tv).\r\n2. This tool was also inspired by [@arzzen](https://github.com/arzzen)'s CLI [tool](https://github.com/arzzen/philips-tv).\r\n3. [@jomwells](https://github.com/jomwells) did a pretty good job of collecting various [ambilight endpoints](https://github.com/jomwells/ambilights).\r\n4. [Some good info](https://gist.github.com/marcelrv/ee9a7cf97c227d069e4ee88d26691019) from [@marcelrv](https://gist.github.com/marcelrv).\r\n\r\n## Contact details\r\nEmail: eslavnov@gmail.com; LinkedIn: https://www.linkedin.com/in/evgeny-slavnov/\r\n", "category": "network", "in": [ { "x": 60, "y": 80, "wires": [ { "id": "b2a881ed54b02798" } ] } ], "out": [ { "x": 990, "y": 60, "wires": [ { "id": "b8fe0854b3997f4c", "port": 0 } ] }, { "x": 990, "y": 120, "wires": [ { "id": "b8fe0854b3997f4c", "port": 1 } ] }, { "x": 1010, "y": 180, "wires": [ { "id": "b8fe0854b3997f4c", "port": 2 } ] } ], "env": [ { "name": "ip", "type": "str", "value": "192.168.178.XX" } ], "meta": { "module": "node-red-contrib-pylips-philips-tv-control", "version": "1.0", "author": "Julian Wiche <julian@wiche.eu>", "desc": "This is a wrapper for the python library pylips to control phillips smart tv's over the network", "keywords": "Phillips philips tv pylips remote control" }, "color": "#3FADB5", "inputLabels": [ "command (msg.payload)" ], "outputLabels": [ "stdout", "stderr", "error code" ], "icon": "font-awesome/fa-tv", "status": { "x": 780, "y": 260, "wires": [ { "id": "9916655622888450", "port": 0 } ] }, "flow": [ { "id": "b8fe0854b3997f4c", "type": "exec", "z": "d3e3e2834d4439c5", "command": "python3", "addpay": "payload", "append": "", "useSpawn": "false", "timer": "", "winHide": false, "oldrc": false, "name": "", "x": 650, "y": 80, "wires": [ [], [], [] ], "inputLabels": [ "command (payload)" ], "outputLabels": [ "stdout", "stderr", "error code" ], "icon": "font-awesome/fa-tv", "info": "# Pylips\nPylips is a Python tool to control Philips TVs (2015+) through their reverse-engineered API. \n\n1. Supports both Android and non-Android TVs\n1. 80+ built-in commands + support for custom \"GET\" and \"POST\" requests to the API\n1. All commands work on TVs with API version 6, most of them also work for API version 5\n1. Full control of Ambilight including color, brightness, mode and 'Ambilight + Hue'\n1. Allows sending TV status updates and receiving commands over MQTT\n\nThe current version of the API does not allow switching input sources anymore. For Android TVs with Google Assistant, Pylips can switch between any input sources that your TV has. For Android TVs without Google Assistant, see some options [here](#switching-input-sources).\n\n## Table of contents ##\n1. [Prerequisites](#prerequisites)\n1. [Setting up Pylips](#setting-up-pylips)\n 1. [New users](#new-users)\n 1. [Migrating from older versions](#migrating-from-older-versions)\n1. [Controlling the TV (manual mode)](#controlling-the-tv-manual-mode)\n 1. [Built-in commands](#built-in-commands)\n 1. [Custom commands](#custom-commands)\n1. [Controlling the TV (MQTT mode)](#controlling-the-tv-mqtt-mode)\n1. [Switching input sources](#switching-input-sources)\n1. [API reference](#api-reference)\n1. [Change log](#change-log)\n1. [TO-DO](#to-do)\n1. [Acknowledgements](#acknowledgements)\n1. [Contact details](#contact-details)\n\n## Prerequisites\n\nProvided that you have python (version 3+) on your system, install all the dependencies first:\n\n```\npip3 install -r requirements.txt\n```\n\nYou may have to use `pip` and `python` instead of `pip3` and `python3` depending on how these tools are installed on your system.\n\n## Setting up Pylips\n\n### New users ###\n\nTo begin using Pylips you first need to add the ip adress of your TV to the [TV] section in the `settings.ini` file. If you want to use MQTT, you will also need to fill in the [MQTT] section and set the required flags in the [DEFAULT] section:\n```\n[DEFAULT]\nverbose = True # show various debug output\nMQTT_listen = False # listen for MQTT commands. Requires correct [MQTT] settings\nMQTT_update = False # publish status updates over MQTT. Requires correct [MQTT] settings\nnum_retries = 3 # number of retries when sending requests. No need to change it unless your network sucks.\nupdate_interval = 3 # interval between updates in seconds (used if MQTT_update = True). Your TV might not appreciate lower values.\n[TV]\nhost = # TV's ip address\nport = # will be discovered automatically, but you can override it here\napiv = # will be discovered automatically, but you can override it here\nuser = # will be discovered automatically (if required for your TV model), but you can override it here\npass = # will be discovered automatically (if required for your TV model), but you can override it here\nprotocol = # will be discovered automatically, but you can override it here\nambihue_node = # will be discovered automatically, but you can override it here\n[MQTT]\nhost = # your MQTT broker's ip address\nport = # your MQTT broker's port\nuser = # your MQTT username\npass = # your MQTT password\nTLS = False # use TLS \ncert_path = # full path to your custom certificate if you are using one, otherwise leave it blank \ntopic_pylips = # Pylips will listen for commands to this topic\ntopic_status = # Pylips will send status updates to this topic\n```\n\nNow turn your TV on and run Pylips without any arguments to complete setting it up (it will discover your TV's API version, port and protocol, and will also pair and save the credentials if required):\n\n`python3 pylips.py`\n\nOnce it's done, you are ready to use Pylips!\n\n**Security note:**\n\nTo pair with the Android TVs 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.\n\n**Custom config path:**\n\nYou can load a custom config by specifying its **absolute** path with a `--config` parameter:\n\n`python pylips.py --config '/home/eslavnov/repos/Pylips/some_settings.ini'`\n\n## Controlling the TV (manual mode) ##\nYou can take advantage of some of the built-in commands or send your own custom commands.\n\n### Built-in commands ###\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command %command%\n```\n\nAny passed arguments will override the settings in `settings.ini` without overwriting them. If you have already run the discovery for new users, you don't have to specify `--host`, `--user` and `-pass` parameters. Also skip the `--user` and `--pass` parameters if your TV does not have Android. Add `--verbose False` to any command if you don't want to see the feedback in your terminal (useful for command line sensors). \n\n\n**Available built-in commands:**\n\n&nbsp; &nbsp; &nbsp; &nbsp; **TV status:**\n1. `powerstate` - Returns current power state of the TV ('On' or 'Off')\n1. `volume` - Returns current volume and mute status\n1. `current_channel` - Returns current channel (if in TV mode)\n1. `current_app` - Returns current app (Android TVs only)\n\n **TV input (only for TVs with Google Assistant):**\n1. `input_hdmi_1` - Switches TV's input to HDMI 1\n1. `input_hdmi_2` - Switches TV's input to HDMI 2\n1. `input_hdmi_3` - Switches TV's input to HDMI 3\n1. `input_hdmi_4` - Switches TV's input to HDMI 4\n\n **TV remote keys:**\n1. `standby` - Sends Standby key\n1. `mute` - Sends Mute key\n1. `volume_up` - Sends VolumeUp key\n1. `volume_down` - Sends VolumeDown key\n1. `channel_up` - Sends ChannelStepUp key\n1. `channel_down` - Sends ChannelStepDown key\n1. `play` - Sends Play key\n1. `pause` - Sends Pause key\n1. `play_pause` - Sends PlayPause key\n1. `stop` - Sends Stop key\n1. `fast_forward` - Sends FastForward key\n1. `rewind` - Sends Rewind key\n1. `next` - Sends Next key\n1. `previous` - Sends Previous key\n1. `cursor_up` - Sends CursorUp key\n1. `cursor_down` - Sends CursorDown key\n1. `cursor_left` - Sends CursorLeft key\n1. `cursor_right` - Sends CursorRight key\n1. `confirm` - Sends Confirm key\n1. `back` - Sends Back key\n1. `home` - Sends Home key\n1. `options` - Sends Options key\n1. `info` - Sends Info key\n1. `find` - Sends Find key\n1. `adjust` - Sends Adjust key\n1. `watch_tv` - Sends WatchTV key\n1. `viewmode` - Sends Viewmode key\n1. `teletext` - Sends Teletext key\n1. `subtitle` - Sends Subtitle key\n1. `record` - Sends Record key\n1. `online` - Sends Online key\n1. `source` - Sends Source key\n1. `ambilight_onoff` - Sends AmbilightOnOff key\n1. `red` - Sends RedColour key\n1. `green` - Sends GreenColour key\n1. `yellow` - Sends YellowColour key\n1. `blue` - Sends BlueColour key\n1. `dot` - Sends Dot key\n1. `digit_0` - Sends Digit0 key\n1. `digit_1` - Sends Digit1 key\n1. `digit_2` - Sends Digit2 key\n1. `digit_3` - Sends Digit3 key\n1. `digit_4` - Sends Digit4 key\n1. `digit_5` - Sends Digit5 key\n1. `digit_6` - Sends Digit6 key\n1. `digit_7` - Sends Digit7 key\n1. `digit_8` - Sends Digit8 key\n1. `digit_9` - Sends Digit9 key\n\n **TV channels:**\n1. `set_channel` - Turns a specified channel on. Requires a valid `--body` argument, see the [API reference](docs/Chapters/Activities-TV-(GET).md) to get it.\n1. `list_channels` - Returns channel list\n1. `list_favorite` - Returns favorite list\n\n **Ambilight:**\n1. `ambilight_on` - Turns ambilight on\n1. `ambilight_off` - Turns ambilight off\n1. `ambihue_status` - Returns the current status of 'Ambilight + Hue'\n1. `ambihue_on` - Turns 'Ambilight + Hue' on\n1. `ambihue_off` - Turns 'Ambilight + Hue' off\n1. `ambilight_color` - Sets ambilight color (in HSB format). Requires a valid `--body` argument: `{\"hue\": 360, \"saturation\": 100, \"brightness\": 255}`\n1. `ambilight_brightness` - Sets ambilight brightness. Requires a valid `--body` argument: `{\"value\": 10}`\n1. `ambilight_video_immersive` - Sets Ambilight to 'Follow video' (Immersive)\n1. `ambilight_video_standard` - Sets Ambilight to 'Follow video' (Standard)\n1. `ambilight_video_natural` - Sets Ambilight to 'Follow video' (Natural)\n1. `ambilight_video_vivid` - Sets Ambilight to 'Follow video' (Vivid)\n1. `ambilight_video_game` - Sets Ambilight to 'Follow video' (Game)\n1. `ambilight_video_comfort` - Sets Ambilight to 'Follow video' (Comfort)\n1. `ambilight_video_relax` - Sets Ambilight to 'Follow video' (Relax)\n1. `ambilight_color_hot_lava` - Sets Ambilight to 'Follow color' (Hot lava)\n1. `ambilight_color_warm_white` - Sets Ambilight to 'Follow color' (Warm white)\n1. `ambilight_color_cool_white` - Sets Ambilight to 'Follow color' (Cool white)\n1. `ambilight_color_fresh_nature` - Sets Ambilight to 'Follow color' (Fresh nature)\n1. `ambilight_deep_water` - Sets Ambilight to 'Follow color' (Deep water)\n1. `ambilight_audio_adapt_brightness` - Sets Ambilight to 'Follow audio' (Energy Adaptive Brightness)\n1. `ambilight_audio_adapt_colors` - Sets Ambilight to 'Follow audio' (Energy Adaptive Colors)\n1. `ambilight_audio_vu_meter` - Sets Ambilight to 'Follow audio' (VU Meter)\n1. `ambilight_audio_spectrum` - Sets Ambilight to 'Follow audio' (Spectrum Analyzer)\n1. `ambilight_audio_knight_rider_1` - Sets Ambilight to 'Follow audio' (Knight Rider Clockwise)\n1. `ambilight_audio_knight_rider_2` - Sets Ambilight to 'Follow audio' (Knight Rider Alternating)\n1. `ambilight_audio_flash` - Sets Ambilight to 'Follow audio' (Random Pixel Flash)\n1. `ambilight_audio_strobo` - Sets Ambilight to 'Follow audio' (Stroboscope)\n1. `ambilight_audio_party` - Sets Ambilight to 'Follow audio' (Party)\n1. `ambilight_audio_random` - Sets Ambilight to 'Follow audio' (Random Mode)\n\n **Other:**\n1. `launch_app` - Launches an app (Android TVs only). Requires a valid `--body` argument. See the [API reference](docs/Chapters/Applications-(GET).md) to get a list of installed apps, find your app in this list and use it as a `--body` argument.\n1. `power_on` - Turns on the TV even if it's in a deep sleep mode. You might need to run `allow_power_on` first, although it was not needed for me.\n1. `allow_power_on` - Allows to remotely power on the TV via chromecast requests.\n1. `google_assistant` - Allows to pass requests to Google Assistant if your model supports it. Requires a `--body` argument containing a `query` with the command that you want to pass to Google Assistant. See example below.\n\n**Examples of using the built-in commands:**\n\nSend Stop key:\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command stop\n```\n\nTurn Ambilight on:\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command ambilight_on\n```\n\nLaunch YouTube:\n```\npython3 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\"}'\n```\n\nLaunch Netflix:\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command launch_app --body '{\"label\":\"Netflix\",\"intent\":{\"component\":{\"packageName\":\"com.netflix.ninja\",\"className\":\"com.netflix.ninja.MainActivity\"},\"action\":\"Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=com.netflix.ninja cmp=com.netflix.ninja/.MainActivity }\"},\"order\":0,\"id\":\"com.netflix.ninja.MainActivity-com.netflix.ninja\",\"type\":\"app\"}'\n```\n\nLaunch Amazon Prime Video:\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command launch_app --body '{\"id\":\"com.amazon.amazonvideo.livingroom\",\"order\":0,\"intent\":{\"action\":\"Intent{act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=com.amazon.amazonvideo.livingroom }\",\"component\":{\"packageName\":\"com.amazon.amazonvideo.livingroom\",\"className\":\"com.amazon.ignition.IgnitionActivity\"}},\"label\":\"Prime Video\"}'\n```\n\nLaunch Kodi:\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command launch_app --body '{\"id\":\"org.xbmc.kodi\",\"order\":0,\"intent\":{\"action\":\"Intent{act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=org.xbmc.kodi }\",\"component\":{\"packageName\":\"org.xbmc.kodi\",\"className\":\"org.xbmc.kodi.Splash\"}},\"label\":\"Kodi\"}'\n```\n\nSwitch input to HDMI 1 using a built-in command (requires Google Assistant):\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command input_hdmi_1\n```\n\nSwitch input to any source (for example, SCART) using Google Assistant directly:\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command google_assistant --body '{\"query\":\"SCART\"}'\n```\n\nControl connected lights in your house using Google Assistant:\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command google_assistant --body '{\"query\":\"Turn on lights\"}'\n```\n\n\n### Custom commands ###\nThe 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). You can also add custom commands to `available_commands.json`.\n\nRead the API reference first to understand available endpoints and how to use them. There are some unexpected things like:\n* Pairing process returns objects like '{\"error_id\":\"SUCCESS\"}' (why, Philips?!)\n* Using strings like 'On'/'Off' for boolean variables (really, Philips?!)\n* 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?)\n\n**Get method:**\n\nTo 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):\n\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command get --path system\n```\n\n**Post method:**\n\nTo 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 for UNIX systems**):\n\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command post --path menuitems/settings/current --body '{\"nodes\":[{\"nodeid\":2131230774}]}'\n```\n\n**For Windows systems**:\n\n```\npython3 pylips.py --host %TV's_ip_address% --user %username% --pass %password% --command post --path menuitems/settings/current --body ^\"{^\"^\"nodes^\"^\":[{^\"^\"nodeid^\"^\":2131230774}]}^\"\n```\n\n## Controlling the TV (MQTT mode) ##\nPylips can connect to your MQTT broker to listen for commands and to publish TV status updates.\n\nEdit the `settings.ini` according to your config and simply run `python3 pylips.py` without any arguments to run in MQTT mode.\n\nEnabling `MQTT_listen` in `settings.ini` will allow you to send commands to a topic specified in `topic_pylips` by posting a JSON message. This works pretty much the same as sending manual commands: your arguments become keys and their values - values of these keys. You can send any commands (POST, GET and built-in), but you won't get anything in return since you are just publishing a message over MQTT. Useful for POST commands that change the state of your TV, but for general GET requests you are better off using the manual mode.\n\nSee examples:\n\n```\n# Let's say we want to change the brightness of ambilight to max (10):\n\n# BUILT-IN COMMANDS\n\n# Manual mode: \npython3 pylips.py --command ambilight_brightness --body '{\"value\":10}'\n\n# MQTT mode: \n{\"command\":\"ambilight_brightness\", \"body\":{\"value\":10}} \n\n\n# POST REQUESTS\n\n# Manual mode: \npython3 pylips.py --command post --path 'menuitems/settings/update' --body '{\"values\":[{\"value\":{\"Nodeid\":2131230769,\"Controllable\":\"true\", \"Available\":\"true\", \"string_id\":\"Brightness\", \"data\":{\"value\":10}}}]}'\n\n# MQTT mode: \n{\"command\":\"post\", \"path\": \"menuitems/settings/update\", \"body\": {\"values\":[{\"value\":{\"Nodeid\":2131230769,\"Controllable\":\"true\", \"Available\":\"true\",\"string_id\":\"Brightness\", \"data\":{\"value\":10}}}]}}\n \n```\n\nEnabling `MQTT_update` in `settings.ini` will publish status updates to `topic_status` like these:\n```\n{\"powerstate\": \"On\", \"volume\": 28, \"muted\": false, \"cur_app\": \"org.droidtv.settings\", \"ambilight\": {\"styleName\": \"FOLLOW_VIDEO\", \"isExpert\": false, \"menuSetting\": \"IMMERSIVE\"}, \"ambihue\": false}\n```\n```\n{\"powerstate\": \"On\", \"volume\": 28, \"muted\": false, \"cur_app\": {\"app\": \"TV\", \"channel\": {\"channel\": {\"ccid\": 644, \"preset\": \"15\", \"name\": \"Comedy Central HD\"}, \"channelList\": {\"id\": \"allcab\", \"version\": \"19\"}}}, \"ambilight\": {\"styleName\": \"OFF\", \"isExpert\": false}, \"ambihue\": false}\n```\n\n## API