Philips Android TV component

Thanks for the info.

I’m only interested in getting the Philips remote control app working for basic channel changing, volume, mouse and keyboard. With everything else I’m way out of my depth here. :blush:

1 Like

OK Everyone after hours and hours and hours of learning,

I have successfully used this post to connect my Philips TV (Model: 43PUT6801/79 Man: June 2017) to my Home Assistant installation.

Frontend

4

Source Select

Achieved Results
With this custom component I am able to connect the TV via a network connection, and am able to view what station it is on and what channel it is, I can also control the volume and power on/off on the TV as well as change the channel source to any other live TV station.

Challenges
Some of the biggest challenges I faced when attempting this was, initially, that I had no knowledge of Python or Linux really for that matter.

My System
My current setup is a Raspberry Pi 3B running Hassio and Home assistant (HA) version 0.78 at the time of writing this.

Steps and Sources of Information:
I was interested in having my Philips TV communicate with Home Assistant.

This was a exciting feature as my current setup has xBox One, ps4, and kodi- libreelec media players sending what is playing to HA. The only device I had one way communication with was the Philips TV, as I was using an IR blaster to control this. Using a "Broadlink IR RM3 mini" and using this home assistant component. Using this I was able to control the TV as if I was using a remote control. However this was not telling my media player to current state of the TV which all other media devices were able to do. There had to be a solution.

See below for my Broadlink media player configuration.yaml before getting this custom component to work:

Media_player:

- platform: broadlink
  name: Philips IR Control
  host: 10.0.4.122
  mac: '78:0f:77:47:90:9e'
  ircodes_ini: 'broadlink_media_codes/philips.ini'
  ping_host: 10.0.4.123

I tried the original joint space API with the Philips TV but my Tv was not supported as I purchased it 2017 and it is Android TV. Found this link in feature requests Philips Android TV component

Reading through this forum I noticed many people were having similar issues with various 2016+ Philips TVs.

The following steps provide this to work.

Gaining a username and password from the Philips 2016+ TV (Android)

  1. Read through the forums and found a Python script to retrieve username and password from the TV.

Script from Post number 2 https://github.com/suborb/philips_android_tv

This script was a little bit confusing for me at first, as it is called philips.py and the custom component Python script is called philips2016.py. from post 2 Hope this clarifies the two different script names.

2 Different Scripts

The Pairing Script

The script by Suborb on github philips.py from post 1 gives the access to retrieve TV credentials from the Philips TV.

  1. Clone git the script to the Linux system ( see here for detailed info about git clone ).

git clone https://github.com/mveken/home_assistant.git

  1. Change the directory to philips_android_tv

cd philips_android_tv

  1. Make sure the TV is on and is connected to a network

  2. Find the IP address of the TV using whatever method you need to e.g. router, Fing, etc

  3. Run the Python script
    python philips.py --host TVHOSTIP_ADDRESS_HERE pair

1

  1. Check the TV for the code that appears on the bottom right hand corner
    and use this code for the next step

  2. Go to a web browser and enter: http://YOURIPADDRESS:1926

  3. Enter the code as directed

You will be presented with a username and password similar to this:

Save these details for later.

The Custom Component Media Player Python Script

The script philips_2016.py from martijnv worked best for my setup
the custom component media player and should be copied into the HA directory:

/config/custom_components/media_player .

Add Custom Media Player to Configuration.yaml

These details will be used in your configuration.yaml file when entering the media player information.

  1. Set up media player in configuration.yaml (Philips 2016+)

     media_player:
     - platform: philips_2016
       name: Philips TV
       host: 192.168.x.x
       username: user from pairing
       password: pass from pairing
    

Save your configuration.yaml and reboot the system.

  1. After system has rebooted check your states and locate the media player you just created

I reason for 2 of the same player is that I have a universal media player also that mimics the active mediaplayer in use see this link

Hope this helps.

5 Likes

I had this working on my Philips 55PUS6412, but after upgrading home assistant to version 0.80.0, I am getting some errors from the py script
“File “/config/custom_components/media_player/philips_2016.py”, line 103, in volume_level
return self._volume / self._max_volume”
Anyone else having issues in the new HA version

I did some digging around, I really wanted to be able to launch apps.

Apparently someone figured it out after I failed (I even forgot that):
Here it is: https://github.com/suborb/philips_android_tv/issues/5#issuecomment-370509253

1 Like

I may try to build a component incorporating everything found here.

Should have checked out this thread way earlier, this is a goldmine of great ways to control that philips tv

1 Like

Just a quick overview of things I got working (using the scripts already shared here):

  • Play and Pause working (There is no PlayPause key (at least for me), so I had to check the actual state and set it to STATE_PLAYING or STATE_PAUSED)
  • Apps as sources instead of channels (since I don’t watch TV and have no sources except Google Play Movies trailers, I wanted to get that working)

Here is the updated philips_2016.py

Be aware that channel switching is not supported anymore in favor of app switching.
I will add a config option later, so you can choose (or maybe enable both)

5 Likes

Constantly made improvements today for the app switching.

Now the current app is shown in the source select box :smiley:

1 Like

i tried the new philips_2016.py and getting errors in the log:
Unable to serialize to JSON: Object of type ‘dict_keys’ is not JSON serializable {‘id’: 2, ‘type’: ‘event’, ‘event’: {‘event_type’: ‘state_changed’, ‘data’: {‘entity_id’: ‘media_player.tvbeneden’, ‘old_state’: <state media_player.tvbeneden=playing; volume_level=0.26666666666666666, is_volume_muted=False, media_content_type=app, media_title=TV, app_name=TV, source_list=dict_keys([‘Help’, ‘Play Store’, ‘YouTube’, ‘Prime Video’, ‘Play Muziek’, ‘Play Games’, ‘Play Films’, ‘Netflix’, ‘Internet Browser’, ‘QuickSupport’, ‘TV-gids’, ‘Opnames’, ‘Bronnen’, ‘Media’, ‘Demomenu’, ‘Appgalerij’, ‘Topselectie’, ‘TV’, ‘Spotify’, ‘Tellybean’, ‘Notifications for Android TV’, ‘ARTE’, ‘Dailymotion’, ‘RTL XL’, ‘NPO’, ‘TV5Monde’, ‘Pathé Thuis’, ‘KIJK’, ‘FOX Sports NL’, ‘Megogo HD’, ‘Deezer’, ‘France24’, ‘Divan.TV’, ‘Social TV’, ‘GameTreeTV GOLD’, ‘Videoland’, ‘Filmbox Live’, ‘MovieMAX Online’, ‘Toon Goggles’, ‘Fishing TV’, ‘VLC’, ‘Instellingen’, ‘Zenders instellen’, ‘Zo kunt u…’, ‘Draadloos en netwerken’, ‘Apps beheren’, ‘Software bijwerken’]), friendly_name=TVbeneden, supported_features=23997 @ 2018-10-24T21:41:18.384159+02:00>, ‘new_state’: <state media_player.tvbeneden=paused; volume_level=0.2833333333333333, is_volume_muted=False, media_content_type=app, media_title=TV, app_name=TV, source_list=dict_keys([‘Help’, ‘Play Store’, ‘YouTube’, ‘Prime Video’, ‘Play Muziek’, ‘Play Games’, ‘Play Films’, ‘Netflix’, ‘Internet Browser’, ‘QuickSupport’, ‘TV-gids’, ‘Opnames’, ‘Bronnen’, ‘Media’, ‘Demomenu’, ‘Appgalerij’, ‘Topselectie’, ‘TV’, ‘Spotify’, ‘Tellybean’, ‘Notifications for Android TV’, ‘ARTE’, ‘Dailymotion’, ‘RTL XL’, ‘NPO’, ‘TV5Monde’, ‘Pathé Thuis’, ‘KIJK’, ‘FOX Sports NL’, ‘Megogo HD’, ‘Deezer’, ‘France24’, ‘Divan.TV’, ‘Social TV’, ‘GameTreeTV GOLD’, ‘Videoland’, ‘Filmbox Live’, ‘MovieMAX Online’, ‘Toon Goggles’, ‘Fishing TV’, ‘VLC’, ‘Instellingen’, ‘Zenders instellen’, ‘Zo kunt u…’, ‘Draadloos en netwerken’, ‘Apps beheren’, ‘Software bijwerken’]), …
21:43 components/websocket_api/http.py (ERROR)

Error executing query: Object of type ‘dict_keys’ is not JSON serializable

1 Like

@Emilio_Emile Sorry, fixed that an hour ago with: https://github.com/nstrelow/ha_philips_2016/commit/c94735f66dc8c15a0b1fdd78be61e2eceb3d2ba5

Please update the custom_component :wink:

Does turn on work for you without the wake-on lan feature?

No, I have not touched the logic concerning the turn_on and off functions.

Basically on/off just sends the “Standby” key, which is not working if the TV is off some time. So WOL is needed.

A workaround I use:
TV is attached to wifi socket. I turn this on/off to turn on the TV. When the TV is on and the power is cut off (so wifi socket goes off), when turning it gets power again it is already on.
Basically I do not put it into standby, but cut the power.

Apps are now sorted in newest version and a bug fix when the no app is opened:

Thank you @nstrelow for these improvements. It is a great addition to the component.
I’ve noticed that you chose to have standby state only if tv reports it. However, when tv goes into sleeping mode after some time, it will be offline. It causes the state of tv showing as ‘playing’ as per your code. Would it be better to use it as the following:

        if self._StateC == 'On':
			self._state = STATE_ON
		else:
			self._state = STATE_OFF

I use universal media player to combine on/off functionality with broadlink IR switch, so the IR switch only turns the tv on but the ‘off’ uses the media player functionality. It gives better control of the factual state of the tv as well as it is recommended to keep OLED tv in standby mode rather than completely disconnect it from power.

after upgrading to 81.0 i got the error:

Update for media_player.tvbeneden fails
Traceback (most recent call last):
File “/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py”, line 221, in async_update_ha_state
await self.async_device_update()
File “/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py”, line 349, in async_device_update
await self.hass.async_add_executor_job(self.update)
File “/usr/local/lib/python3.6/concurrent/futures/thread.py”, line 56, in run
result = self.fn(*self.args, **self.kwargs)
File “/usr/local/lib/python3.6/site-packages/homeassistant/util/init.py”, line 324, in wrapper
result = method(*args, **kwargs)
File “/config/custom_components/media_player/philips_2016.py”, line 220, in update
self._tv.update()
File “/config/custom_components/media_player/philips_2016.py”, line 301, in update
self.getChannel()
File “/config/custom_components/media_player/philips_2016.py”, line 319, in getChannel
self.app_name = app[“label”]
KeyError: ‘label’

It is working by the way :wink:

@Emilio_Emile
do you already have the newest version?
I had a bug when your TV was in the Home Menu (Leanback Launcher) as no label is reported then
Pls check if you have the newest from GitHub:

I have the same issue and use the latest version. Actually, it was before I updated to 0.81.0.

2018-10-28 12:18:40 ERROR (MainThread) [homeassistant.helpers.entity] Update for media_player.philips_tv fails
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 221, in async_update_ha_state
    await self.async_device_update()
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 349, in async_device_update
    await self.hass.async_add_executor_job(self.update)
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/util/__init__.py", line 324, in wrapper
    result = method(*args, **kwargs)
  File "/config/custom_components/media_player/philips_2016.py", line 220, in update
    self._tv.update()
  File "/config/custom_components/media_player/philips_2016.py", line 301, in update
    self.getChannel()
  File "/config/custom_components/media_player/philips_2016.py", line 319, in getChannel
    self.app_name = app["label"]
KeyError: 'label'
2018-10-28 12:18:47 ERROR (MainThread) [homeassistant.helpers.entity] Update for media_player.philips_tv fails
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 221, in async_update_ha_state
    await self.async_device_update()
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 349, in async_device_update
    await self.hass.async_add_executor_job(self.update)
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/util/__init__.py", line 324, in wrapper
    result = method(*args, **kwargs)
  File "/config/custom_components/media_player/philips_2016.py", line 220, in update
    self._tv.update()
  File "/config/custom_components/media_player/philips_2016.py", line 301, in update
    self.getChannel()
  File "/config/custom_components/media_player/philips_2016.py", line 319, in getChannel
    self.app_name = app["label"]
KeyError: 'label'

quick fix:

    def getChannel(self):
    if self.on:
        rr = self._getReq('activities/current')
        if rr:
            if rr["component"]["packageName"] == "org.droidtv.zapster":
                r = self._getReq('activities/tv')
                self.channel_id = r.get("channel", {}).get("preset")
                self.channel_name = r.get("channel", {}).get("name")
                self.media_content_type_1 = "channel"
            else:
                self.media_content_type_1 = "app"
                pkgName = rr.get("component", {}).get("packageName")
                if pkgName == 'com.google.android.leanbacklauncher':
                    self.app_name = 'LeanbackLauncher'
                    self.channel_name = self.app_name
                else:
                    app = self.pkgNameToApp.get(pkgName, {})
                    self.app_name = app["label"]
                    self.channel_name = self.app_name

Is the syntax correct? I get errors when I try to replace the cod with this fix.

What kind of error do you get? I only added

if self.on:

You would need to add the correct spacing:

def getChannel(self):
  if self.on:
    rr = self._getReq('activities/current')
    ......

Thanks @JSON_v62 for the neat fix :slight_smile:

I will build some better handling of the ON/OFF state in the next version, also including your improvements @Molodax