AndroidTV Binding [3.2.0;4.2.0)

Yes that’s exactly correct. You can just send the numerical value to the KEYCODE channel for whatever you need. Example, KEY_PLAY to KEYPRESS is the same as 126 to KEYCODE.

To note, buttons above 255 haven’t been tested, if you do, plesse report success or failure.

To elaborate on this, those codes are defined by Google as part of the protocol. I didn’t create them. The binding just allows you to pass those commands through. They work great in many places. Saddly and oddly things like the hdmi input codes don’t seem to work (probably because of how each TV is designed).

Dumb question, pause works right? The hex string we send is weird for the number 127, just making sure it’s working right.

I’ll build a player channel next time I get time to sit at a keyboard. Maybe later today, maybe later this week, not sure what my schedule looks like yet. It’s not hard, just requires some time to hit all the files.

EDIT: probably going to be near end of the week before I can get to this.

Yes :+1:


Nice!


Until this is implemented I made my own solution. Essentially it compares the target State (in the following Multimedia_Wohnzimmer_Fernseher_Laustaerke_Soll) to the current state (in the following Multimedia_Wohnzimmer_Fernseher_Laustaerke_Ist) and sends volume up or down commands until the states are the same. For anyone who is interested in this solution here it is:

  1. Items:

    Group     Multimedia_Wohnzimmer_Fernseher_Alexa_Endpunkt     "Fernseher"                                                                                                                      {alexa="TV"}
    Dimmer    Multimedia_Wohnzimmer_Fernseher_Laustaerke_Ist                                                                                                                                      {channel="androidtv:googletv:Multimedia_Wohnzimmer_Fernseher:volume"}
    Dimmer    Multimedia_Wohnzimmer_Fernseher_Laustaerke_Soll    "Lautstärke [%d %%]"                                       <soundvolume>     (Multimedia_Wohnzimmer_Fernseher_Alexa_Endpunkt)    {alexa="VolumeLevel" [increment=5]}
    

    or without the alexa config

    Dimmer    Multimedia_Wohnzimmer_Fernseher_Laustaerke_Ist                                                    {channel="androidtv:googletv:Multimedia_Wohnzimmer_Fernseher:volume"}
    Dimmer    Multimedia_Wohnzimmer_Fernseher_Laustaerke_Soll    "Lautstärke [%d %%]"       <soundvolume>
    
  2. Rules:

    import java.util.concurrent.locks.ReentrantLock
    
    val String Dateiname = "Multimedia.rules"
    
    
    val ReentrantLock FernseherLautstaerkeLock = new ReentrantLock
    
    
    rule "Fernseher Lautstärke"
    when
        Item Multimedia_Wohnzimmer_Fernseher_Laustaerke_Soll received command
    then
        val String RuleName = Dateiname + ": \"Fernseher Lautstärke\": "
    
        logInfo("Rule triggered", RuleName + receivedCommand)
    
        val Number IstStand = Multimedia_Wohnzimmer_Fernseher_Laustaerke_Ist.state
        val Number SollStand = Multimedia_Wohnzimmer_Fernseher_Laustaerke_Soll.state
        val Number Unterschied = Math::abs((SollStand - IstStand).floatValue).intValue
    
        logInfo("Rule triggered", RuleName + "Ist-Zustand: " + IstStand + ", Soll-Zustand: " + SollStand + " (Unterschied: " + Unterschied + ") ")
    
        var String Kommando
        if (SollStand == IstStand) {
            logInfo("Rule triggered", RuleName + "Der Soll-Zustand entspricht dem Ist-Zustand")
            return
        }
        else if (SollStand > IstStand) Kommando = "KEY_VOLUP"
        else Kommando = "KEY_VOLDOWN"
    
        logDebug("Rule triggered", RuleName + "Gesendetes Kommando: " + Kommando)
    
        FernseherLautstaerkeLock.lock()
    
        for(var i=1; i<=Unterschied; i++) {
            Multimedia_Wohnzimmer_Fernseher_Knopfdruck.sendCommand(Kommando)
    
            // Nun etwas warten, da so sie Lautstärke langsam steigt/sinkt statt schlagartig
            Thread.sleep(100)
        }
    
        Thread.sleep(1000)
        FernseherLautstaerkeLock.unlock()
    end
    
    
    rule "Fernseher Laustärke Soll-Zustand aktualisieren, wenn der Ist-Zustand sich ändert" // z.B. über die Fernbedienung
    when
        Item Multimedia_Wohnzimmer_Fernseher_Laustaerke_Ist changed
    then
        val String RuleName = Dateiname + ": \"Fernseher Laustärke Soll-Zustand aktualisieren, wenn der Ist-Zustand sich ändert\": "
    
        if (FernseherLautstaerkeLock.isLocked()) { return }
    
        val Number IstStand = Multimedia_Wohnzimmer_Fernseher_Laustaerke_Ist.state
        logInfo("Rule triggered", RuleName + IstStand)
    
        Multimedia_Wohnzimmer_Fernseher_Laustaerke_Soll.postUpdate(IstStand)
    end
    

    The first rule is to send commands until the target state equals the current state. The seconds rule is to update the target state if the current state changes (e.g. by a remote)

Can you show the source of this / where you found them?

This sounds like probably no solution to the aforementioned problems, right?

That may take a minute, I pulled it out of a reference document I found and I can’t seem to find it now. I have found it on a few similar projects on github and thus far they seem to work as expected when they do work. All we do on our side is send the number over to the device for handling.

@Felix_Schneider I’ve added a player item to the binding. I’m not near my shield to test it out, but the code all looks sound. Would you mind testing this jar out to see if it works as expected?

https://github.com/morph166955/openhab-addons/releases/download/androidtv-beta/org.openhab.binding.androidtv-3.2.0-4.0.0-SNAPSHOT-3f6800c.jar

Finally found it…

https://developer.android.com/reference/android/view/KeyEvent

Works at expected, tested all four commands with my google TV. Thanks!


Nice! I searched through these commands to see if there any interesting ones in the list. Behold, there are commands for screen brightness up and down and one command for captions. Sadly none of them seem to work. When sending the first to the TV doesn’t even react, with the latter one, the light (which acknowledges a command) blinks but to action is done.

Really seems like (some of) these commands are vendor-specific :slightly_frowning_face:

Awesome! There are actually 6 buttons programmed. PLAY, PAUSE, NEXT, PREVIOUS, FASTFORWARD, REWIND. From what I could tell from the developer docs those are the ones that the player type accepts so I grabbed them all.

It definitely is. Unfortunately. I was REALLY hoping the HDMI input changes would work but sadly they don’t seem to. You need to remember that while it’s an AndroidTV, each vendor has a different app (or set of apps) to handle the tv functions. For example, Sony uses com.sony.dtv.tvx which is an embedded Bravia app for the device to handle those vendor specific features. This binding, through the GoogleTV protocol basically acts as a middle man. It just sends/forwards the commands to the bus on the TV. If the app isn’t looking for those commands, they are effectively ignored.

Pushed version 0.09 (3f6800c) as posted above. This adds the player channel.

1 Like

I’m trying to work through an issue thats happening on the DirecTV boxes right now, looking to see how many people may be impacted. The observed behavior is that after several days pass all key functions seem to stop. The binding doesn’t go offline and we still get heartbeats from the stack. Has anyone else noticed this?

Hi, I installed several versions of your binding, and every time I was
very happy to use it, But after some time the installed version stopped
working. Probably the reason is that you are still developing it…
However I would be very happy to have a version that continually
works, even if it does not have new features. Would this be possible?
Best regards!

It would be helpful if you provide details on how it stops working. Otherwise, @morph166955 has no way to know what your problem is or how to fix it.

The binding is basically baked actually at this point. I’m not doing any major changes. The posted version is what’s in the PR pending review for stable merge. Only adding small features at this point. If something is broken please let me what’s not working so we can get it fixed. If you can put the binding logging into trace mode and send it to me via DM that would be great. It should show me what’s broken.

1 Like

I’ll install your latest version and send you the logs, if there are problems.

Sounds good. Don’t forget you need to run the pin process twice on a shield so it gets both protocols.

Just a warning.

In OH 3 and 4, unlike in OH 1 and 2, only one instance of any given rule can run at a given time. If the rule is triggered while it’s already running it will queue those events and work them off in sequence in order. So you can never have a case where you need a ReentrantLock to protect a single rule. But here you are locking two rules.

This brings me to the warnings. First of all, you are not using try/catch/finally so you can never guarantee that the lock is unlocked if there’s any sort of error. Second of all, not all errors bubble back up to your rule so even with a try/catch/finally, for certain types of errors, you still can’t guarantee that the lock will be released.

This is just a temporary rule so it’s probably not that big of a deal. But for any long term rule, an approach that doesn’t rely on Rules DSL and Java ReentrantLocks should be found. It might be good enough to just use a boolean variable or a Switch Item would be even better as you could unset the lock in a case where it failed to become unlocked. Or pretty much all of the other rules languages do not have as much of this problem dealing with locks.

1 Like

@morph166955 - I just installed the 3.4 version from Marketplace to test it with a Chromecast with Google TV (4K). I created the thing from discovery and linked a new item to the pincode channel. Then from the console:

openhab> openhab:update GoogleTV_PinCode REQUEST
Update has been sent successfully.

But nothing happens on the screen, and I don’t see “User Forced PIN Process” logged (having TRACE level enabled). Any clues - more logs needed?

I have this continuously logged:

2023-04-02 11:50:41.833 [TRACE] [l.googletv.GoogleTVConnectionManager] - xxx- Device Health - Online: false - Logged In: false
2023-04-02 11:50:41.888 [TRACE] [l.googletv.GoogleTVConnectionManager] - xxx- Device Health - Online: false - Logged In: false

Shouldn’t it be openhab:send not openhab:update for a command?

Also if you’re seeing online as false in that message it could indicate a network issue. Online in this case is a service ping (code was based off the network binding). If it’s showing as offline that means we cant even establish a socket connection to the port on the device. I’d try to delete and rebuild the thing and see what happens.