Philips Android TV component


#102

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.


#103

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


#104

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.


#105

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:


#106

@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:


#107

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'

#108

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

#109

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


#110

What kind of error do you get? I only added

if self.on:


#111

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


#112

Thank you. I’m looking forward to seeing the updated version since couldn’t implement the fix even with the correct spacing.


#113

Hi, I’ve noticed a problem after I made the chromecast built in always available the TV doesn’t disconnect from the network. I’ve it connected via a LAN cable and now the component doesn’t detect the tv as online/powered on.

If I restart Home assistant with the TV powered on than the component detects that the TV is on and displays the correct source.


#114

The on/off detection is flawed. The next iteration will improve this. @JSON_v62 did some awesome work on that and shared it with me. I will release the updated stuff this evening probably. Wanted to do some more tests with Wake-On-LAN (or WLAN) to see if I can get that to work for me.


#115

Please post ideas or errors here, so we can make this better

Time for a new iteration/version (most new findings come from @JSON_v62):

  • Improve power state handling a lot thanks to the /powerstate command
  • Use wake-on-lan to wake the TV when in standby (for this to work: add mac to your config and enable WoWLAN, see below)
  • Fixed some app[‘label’] errors and other improvements and fixes

The handling of the powerstate is still not perfect and may not update very quickly for now. Please share if you encounter wrong behavior of the component.

To be able to turn your TV On from Standby you have to:

  • connect it to Wifi (That’s at least what worked for me, maybe there is a way to make it work for LAN)
  • enable WoWLAN under Settings->Wireless&Networks->Wired&Wifi->Switch on with Wi-Fi (WoWLAN)
  • add a line with the Wifi MAC address to your config, e.g.:
media_player:
  - platform: philips_2016
    name: TV
    host: 192.168.1.111
    mac: aa:aa:aa:aa:aa:aa
    username: xxxxx
    password: xxxxx

As always you can find the updated component here:


#116

Ideas to further improve this component:

  • Add full support to discovery, including generating user/pw and finding out Mac address
    It should be possible with only the IP to get system information. Then pair the TV. And then get the Mac address needed for WoWLAN using the /network/devices command.

  • Using the API it is currently not possible to check whether a video is playing or paused. A LOT of commands are possible through ADB (Android Debug Bridge), which is fairly easy to turn on. I already found some commands that could at give info about what app is currently playing
    adb shell dumpsys media_session for those curious
    This could actually be it’s own plugin, e.g. a component for controlling Android devices through ADB


#117

@nstrelow Thank you for the quick reply and the quick relase. I just wanted to pin point this because the component was working great for 3 months.

Thank everyone who is working on this component it’s been a saver as I have replaced my Sony lcd with Philips Oled.


#118

i tried the new component… but what i can see is… that when the TV is on and an App is loaded (like videoland)… it is not updating anymore:

Update for media_player.philips_tv fails
Traceback (most recent call last):
File “/usr/src/app/homeassistant/helpers/entity.py”, line 221, in async_update_ha_state
await self.async_device_update()
File “/usr/src/app/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/src/app/homeassistant/util/init.py”, line 324, in wrapper
result = method(*args, **kwargs)
File “/config/custom_components/media_player/philips_2016.py”, line 226, in update
self._tv.update()
File “/config/custom_components/media_player/philips_2016.py”, line 309, in update
self.getChannel()
File “/config/custom_components/media_player/philips_2016.py”, line 331, in getChannel
self.app_name = app[“label”]
KeyError: ‘label’


#119

Oh well, I was sure I fixed it, but forgot to upload it. FIXED IT NOW!
https://github.com/nstrelow/ha_philips_2016/blob/master/philips_2016.py (Haven’t test run it, as I am not home, should work, but no guarantees)

This essentially happens when an activity/app is displayed, which is not included in /applications.
Examples are “NA” or “LeanbackLauncher”. Somehow you trigger more examples, that’s why now if the app is not included in applications, just the packageName is displayed.

So:
If there is an app name, this name is displayed
If not, the packageName (com.android.google.youtube) or something else is displayed.
Please share what is displayed otherwise, I would love to know what other exceptions there are


#120

Can this be something https://github.com/home-assistant/home-assistant/pull/16975 in regard to further improvements to check whether a video is playing or paused? It looks like it is still in progress, so maybe you @nstrelow could contribute to it so it would work with new Philips Tvs too?


#121

sure I will check my apps and post the package name here…

I made some changes to the source because I think the powerstate is not function correct. And I can’t turn on the television etc.
I checked the older versions and I’m working now with the StateC.

from homeassistant.const import (CONF_HOST, CONF_MAC, CONF_NAME, CONF_USERNAME, CONF_PASSWORD,
STATE_OFF, STATE_ON, STATE_IDLE, STATE_UNKNOWN, STATE_PLAYING, STATE_PAUSED)

def init
self._StateC = None

def StateC(self):
“”“Return the device name.”""
return self._StateC

def update(self):
self._StateC = self._tv.StateC
if self._StateC == ‘On’:
self._state = STATE_ON
elif self._StateC == ‘Standby’:
self._state = STATE_OFF
else:
self._state = STATE_OFF

def getStateC(self):
    r = self._getReq('powerstate')
    if r:
        self.StateC = r['powerstate']


def turn_on(self):
    """Turn on the device."""
    #self._tv.setPowerState('On')
    i = 0
    self.wol()
    self._tv.sendKey('Standby')
    self._state = STATE_ON

If you want my file just say it.