AndroidTV Binding [3.2.0;4.2.0)

For anyone tracking the PRs, I’ve split off some of the non-Philips specific bits into a second PR to try to get this through the review cycle a little easier. This will also let me maintain the main part of the binding easier as Philips will be able to stand on it’s own. [androidtv] Fixes Bugs and Prepares for PhilipsTV by morph166955 · Pull Request #16191 · openhab/openhab-addons · GitHub is the new PR, [androidtv] Add PhilipsTV protocol to AndroidTV by morph166955 · Pull Request #15352 · openhab/openhab-addons · GitHub is still the Philips PR (it will have to be rebased once 16191 is merged in).

1 Like

Good morning (or afternoon) to everyone! As I mentioned a while ago, supporting OH3.x is becoming more and more complicated as the days are going on. I believe we’re at the critical mass point now that 4.1 is released to pull back support to 4.x only. Before I go and pull this trigger I wanted to poll the community to see the overall impact. To note, I’ll leave the last 3.x compatible version posted on a different thread to support those folks, there just won’t be any new development or bug fixes. If you’re still on 3.x and use this binding from the marketplace, can you just like this thread so I can get a feel for the size of the community. Thank you!

1 Like

Apparently it’s just me.

It’s just as well if you drop support for 3.x, which will theoretically replace my recent lack of motivation with another good reason to update to 4.1. :wink:

I’ve pushed an update to the main thread (d478d97). This is still compatible with 3.2.0 and up. I was able to resolve the build issues I was having with the compatibility (for now).

Some key things to note. This is equivalent to the most current 4.2.0 SNAPSHOT plus the PhilipsTV protocol PR ([androidtv] Add PhilipsTV protocol to AndroidTV by morph166955 · Pull Request #15352 · openhab/openhab-addons · GitHub).

There are several bug fixes included in this for the GoogleTV and ShieldTV protocol so I would suggest updating. Also to note, there is a breaking change here (which most people wouldn’t likely be impacted by). “port” is now “googletvPort” and “shieldtvPort” under the thing parameter configurations. This is only impactful if for some reason you configured this beyond the default ports.

Enjoy!

1 Like

I’m getting the following error on startup:

2024-01-21 17:11:06.788 [WARN ] [re.xml.osgi.XmlDocumentBundleTracker] - The XML document '/OH-INF/addon/addon.xml' in module 'org.openhab.binding.androidtv' could not be parsed: 
---- Debugging information ----
cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message       : discovery-methods
class               : java.util.ArrayList
required-type       : java.util.ArrayList
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /addon/discovery-methods
line number         : 11
class[1]            : org.openhab.core.addon.internal.xml.AddonInfoXmlResult
required-type[1]    : org.openhab.core.addon.internal.xml.AddonInfoXmlResult
converter-type[1]   : org.openhab.core.addon.internal.xml.AddonInfoConverter
version             : 1.4.20
-------------------------------
com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message       : discovery-methods
class               : java.util.ArrayList
required-type       : java.util.ArrayList
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /addon/discovery-methods
line number         : 11
class[1]            : org.openhab.core.addon.internal.xml.AddonInfoXmlResult
required-type[1]    : org.openhab.core.addon.internal.xml.AddonInfoXmlResult
converter-type[1]   : org.openhab.core.addon.internal.xml.AddonInfoConverter
version             : 1.4.20
-------------------------------
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:81) ~[?:?]
        at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72) ~[?:?]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:68) ~[?:?]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:52) ~[?:?]
        at org.openhab.core.addon.internal.xml.AddonInfoConverter.unmarshal(AddonInfoConverter.java:77) ~[?:?]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:74) ~[?:?]
        at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72) ~[?:?]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:68) ~[?:?]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:52) ~[?:?]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:136) ~[?:?]
        at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32) ~[?:?]
        at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1464) ~[?:?]
        at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1441) ~[?:?]
        at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1389) ~[?:?]
        at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1341) ~[?:?]
        at org.openhab.core.config.core.xml.util.XmlDocumentReader.readFromXML(XmlDocumentReader.java:105) ~[?:?]
        at org.openhab.core.config.core.xml.osgi.XmlDocumentBundleTracker.parseDocuments(XmlDocumentBundleTracker.java:396) ~[?:?]
        at org.openhab.core.config.core.xml.osgi.XmlDocumentBundleTracker.processBundle(XmlDocumentBundleTracker.java:382) ~[?:?]
        at org.openhab.core.config.core.xml.osgi.XmlDocumentBundleTracker$2.run(XmlDocumentBundleTracker.java:347) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
        at java.lang.Thread.run(Thread.java:840) ~[?:?]
Caused by: com.thoughtworks.xstream.mapper.CannotResolveClassException: discovery-methods
        at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:81) ~[?:?]
        at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[?:?]
        at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55) ~[?:?]
        at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[?:?]
        at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88) ~[?:?]
        at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[?:?]
        at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79) ~[?:?]
        at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[?:?]
        at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74) ~[?:?]
        at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[?:?]
        at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:71) ~[?:?]
        at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[?:?]
        at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47) ~[?:?]
        at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29) ~[?:?]
        at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readBareItem(AbstractCollectionConverter.java:131) ~[?:?]
        at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:117) ~[?:?]
        at com.thoughtworks.xstream.converters.collections.CollectionConverter.addCurrentElementToCollection(CollectionConverter.java:99) ~[?:?]
        at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:92) ~[?:?]
        at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:86) ~[?:?]
        at com.thoughtworks.xstream.converters.collections.CollectionConverter.unmarshal(CollectionConverter.java:81) ~[?:?]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:74) ~[?:?]
        ... 24 more

Not sure if this is the cause, but the media control channel doesn’t seem to be working either. When I pause/play from my ShieldTV’s remote, the OpenHAB channel never gets updated.

I must have missed that on the compile. I assume youre on 3.x? Ill drop a new one shortly, we pushed a bunch of changes today from the review. Just wrapping a few small things up first.

I’m on OpenHAB 4.0.0 release build.

I had a quick look at the code and I don’t see anything related to getting the mediaplayer state from the ShieldTV. Am I overlooking something or is this not supported?

I’ll go check that out. We haven’t changed that file in a long time, not sure why it’s throwing issues.

You are correct, we do not get state from the shield. We only send commands through that.

Do you know if the Shield sends that information? If so I might spend some time to add support for it.

I use this information to automatically dim the lights when playing movies.

I have not found anything in either STV or GTV which sends it. I pull that info from other bindings for my automation (e.g. Plex). If you find something in either please let me know I’m always looking to make the protocol stack more robust.

I found the offending issue. Apparently a breaking change was implemented to the xml schema for the addons.xml at the very end of the 4.1 release cycle. It’s causing backwards compatibility issues.

We’re on the last few changes of having the PhilipsTV code merged in. As soon as that’s done I’ll drop a new jar for everyone with the fixes for the xml included.

The ADB plugin can pull that information, but it polls the device. In the current plugin the minimum polling interval is 10 seconds so I had to make a modified version to reduce it to 1 second.

I’ll have a look at the low level protocol dumps to see if the device sends that information.

Please let me know if you find anything in the protocols. ADB works a bit differently and I’ve been avoiding adding that in here. I’ve been relatively successful decoding both protocols thus far and haven’t found anything in either to indicate a play state.

Hi! I just tried this binding with my philips ambilight OLED TV (48oled707), I’m on OH4.1.1, I downloaded this from the OP: https://github.com/morph166955/openhab-addons/releases/download/androidtv-beta/org.openhab.binding.androidtv-3.2.0-4.2.0-SNAPSHOT-d478d97.jar. I was able to connect phillipsTV with the pin (actually it it was a four digit pin not 6 as it was written it the OP), but after when I tried again the pincode REQUEST nothing happened. The thing is not online as it still missing the googleTV authentication. Moreover, the openhab log is full with an error messige that the port 6467 is closed. I dont understand, in the OP is is written that the bindig uses the 6466 port. I tried to set the port manually in the text config file to 6466 but it did not help. Could someone help me? What do I do wrong? My config files:

.things:
Thing androidtv:googletv:bedroom [ ipAddress=“192.168.0.186” ]

.items:
Switch PhilipsTV_POWER “POWER” { channel = “androidtv:philipstv:bedroom:power” }
Dimmer PhilipsTV_VOLUME “VOLUME [%s]” { channel = “androidtv:philipstv:bedroom:volume” }
Switch PhilipsTV_MUTE “MUTE [%s]” { channel = “androidtv:philipstv:bedroom:mute” }
String PhilipsTV_TVCHANNEL “TVCHANNEL [%s]” { channel = “androidtv:philipstv:bedroom:tvChannel” }

6466

It sounds like you don’t have the googletv stack installed on the device. You’re correct 6466 is the correct port. 6467 is used by the PIN process behind the scenes. If 6467 isn’t connecting then I would check the TV. Are you able to connect through the googletv app and control the device? Thats a good sanity check.

Yes, when i try google tv app from my phone the the shows the pin/pairing screen and after it I can control the TV from the app. I tried to remove the binding and reinstall, but nothing is changed. I still have th erros in the log:

2024-02-09 22:46:10.541 [INFO ] [philipstv.PhilipsTVConnectionManager] - Pairing code for tv authentication is missing. Starting initial pairing process. Please provide manually the pairing code shown on the tv at the configuration of the tv thing.
2024-02-09 22:46:10.607 [INFO ] [l.philipstv.pairing.PhilipsTVPairing] - The pairing code is valid for 60 seconds.
2024-02-09 22:46:15.463 [INFO ] [l.googletv.GoogleTVConnectionManager] - bedroom - Error opening SSL connection to 192.168.0.186:6467 Connection timed out
2024-02-09 22:46:43.564 [INFO ] [philipstv.PhilipsTVConnectionManager] - Pairing code is available, but username and/or password is missing. Therefore we try to grant authorization and retrieve username and password.
2024-02-09 22:47:22.151 [INFO ] [l.googletv.GoogleTVConnectionManager] - bedroom - Error opening SSL connection to 192.168.0.186:6467 Connection timed out

and

024-02-09 23:08:57.749 [WARN ] [ocol.philipstv.service.VolumeService] - Error during handling the VolumeService command REFRESH for Channel volume: status code: 401, reason phrase: The given username/password combination is invalid.
org.apache.http.client.HttpResponseException: status code: 401, reason phrase: The given username/password combination is invalid.
	at org.openhab.binding.androidtv.internal.protocol.philipstv.ConnectionManager.validateResponse(ConnectionManager.java:101) ~[?:?]
	at org.openhab.binding.androidtv.internal.protocol.philipstv.ConnectionManager.doHttpsGet(ConnectionManager.java:72) ~[?:?]
	at org.openhab.binding.androidtv.internal.protocol.philipstv.service.VolumeService.getVolume(VolumeService.java:87) ~[?:?]
	at org.openhab.binding.androidtv.internal.protocol.philipstv.service.VolumeService.handleCommand(VolumeService.java:62) ~[?:?]
	at org.openhab.binding.androidtv.internal.protocol.philipstv.PhilipsTVConnectionManager.refreshTvProperties(PhilipsTVConnectionManager.java:622) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
	at java.lang.Thread.run(Thread.java:840) [?:?]

I don’t know if it important or not but I use openhab in docker (on a synology).
Do you have any ideas what do I do wrong?

That’s definitely a new one. Just as a test, can you define it as a googletv device instead of philipstv to see if the google PIN works standalone? The docker could definitely be the cause also. How do you have the network configured?

Dear @morph166955,

Problem solved. It seems it was some kind of network issue because after I restarted the router and the TV itself the problem gone away. Anyway, thank you for your help! Now the bindig is working.

I have an other question: I tried the ambilight lounge channel and I’m able to switch it on but I can’t change the colour of the ambilight longe. Do you know how to do this?

hey is there a possibility to switch apps on googletvs? Just found the solution for shieldtvs

Not sure what you are referring to. Can you elaborate?