Vizio TV Integration

Alright!

But copy that command line because you only have so long to do it and you need to execute the two steps in a short time.

  1. You already have it, it gives you a code
  2. Then do this with the same DEVICE_ID and use the PIN and PAIRING_TOKEN you got back >>>>
curl -k -H "Content-Type: application/json" -X PUT -d "{\"DEVICE_ID\": \"12345\",\"CHALLENGE_TYPE\": 1,\"RESPONSE_VALUE\": \"####\",\"PAIRING_REQ_TOKEN\": ######}" https://192.168.2.90:7345/pairing/pair

You might not be in Windows. I am, hence the extra escape /'s.
I put those commands in a text editor so I can easily copy/paste.
You will need to do the first one again probably and then use the RESPONSE_VALUE (which is the PIN on the TV) and the TOKEN you got.

Once you do this you will never need to do it again.

When you succeed at both steps, the second response would be like this:

{"STATUS": {"RESULT": "SUCCESS", "DETAIL": "Success"}, "ITEM": {"AUTH_TOKEN": "Zjisdhsdiu"}}

That AUTH_TOKEN is what you want to record/write down … that is the secret that allows you to speak to your TV via the REST commands

So after getting mu auth code from the TV i added the below code to my config file and restarted.

Once restarted i get the below error, is there something else i need to install to my server first?

# vizio auth token Zuw2f5k69n
vizio_processkey:
  url: "https://10.1.1.102:7345/key_command/"
  method: put
  content_type: "application/json"
  headers:
    AUTH: "Zuw2f5k69n"
  payload: '{"KEYLIST": [{"CODESET": {{ codeset | int }},"CODE": {{ code | int }},"ACTION":"KEYPRESS"}]}'
  verify_ssl: false

That is a rest_command sensor. So you if you are putting that in your main configuration, then you would need:

rest_command:
    vizio_processkey:

I always use includes so the integration is on the include line.

ok i appear to have that working.

the only thing that i cant figure is selecting apps and hdmi inputs

The command “Cycle Input” should open the list of inputs. If you attach it to a button you can click the button and cycle through them and stop at the one you want. You can also navigate smartcast with buttons that send up/down/select

Or there are some other commands to go direct

I tried using click-hold, but I use tap now.

In other words. Send it 7,1

Did you get things going? I have mostly finished everything now. I had to add Broadlink IR for an older Vizio Soundbar and a Denon Receiver for volume control on two of the zones. I am also going to add some DirecTV audio output into my DAX 88 receiver for football season to broadcast games on the 8 zone stereo. But otherwise it all works great.

Yes it’s all working. Many thanks. I would like to add a play pause and forward/rewind keys but as they arnt on the original remote I don’t think I can do those.

I believe play/pause is the same as select button when CAST is on. I have not tested arrows but that maybe the same. I will look at that today

I tested this and it behaves as I thought. If you are speaking of the Vizio TV in Casting, I started up Netfix and the left/right arrows in my remote for navigation behave as rewind/fast forward and the OK button is a toggle play/pause.

image

Same behavior in YouTube although the TV GUI is different but those commands left/right/OK in navigation are rwd/ff/play-pause while streaming.

By the way, I am going to replace some this in the near future. Right now I had a single button for power but I think I will replace with an input select. You can choose “power off” or select like “Netflix”. If you select Netfix it would power up and go directly there. Then eliminate the “Input” toggle and the “Power” button … and eliminate the direct Netflix, Prime, HBO Max, YouTube buttons and compact the GUI. Cast will still be an option so you can always go there and navigate.
image

@kbrown01 : Did you ever publish your integration anywhere?
I’m still chasing my tail on getting my Vizios integrated.

-mrmike

@mrmike1313 … I just finished posting some Inkbird iBBQ-4T cooking probe code. I wanted to finish a few changes for the Vizio + Cast + DirecTV remotes and then will post the whole code. I am hoping to finish the changes today.

1 Like

I just finished the changes to enable this in the remote, just need to plug it into the interface now. You know, the wife rules them all and she wanted to get rid of the “input” tap…tap…tap to select what she wanted to do. Now I have this which immediate will turn on the TV if it isn’t on, then select the input directly (or turn it off if that is what you want):

1 Like

OK. Took me a bit to adjust things (mostly because I have four Vizio’s and four DirecTV boxes) but it is 95% complete. I have some events tonight and tomorrow and then this weekend I should have it all put up on Git.

1 Like

Been following this as I am integrating a vizio as well, thank you for all the support!

Do you have to write in each button like you have there? Or are you using a dictionary file to store the codes and events?

For the Vizio I use the rest interface so I have a rest_command.yaml included that contains this:

vizio_processkey:
  url: 'https://{{ ip }}:{{ port }}/key_command/'
  method: put
  content_type: "application/json"
  headers:
    AUTH: '{{ auth }}'
  payload: '{"KEYLIST": [{"CODESET": {{ codeset | int }},"CODE": {{ code | int }},"ACTION":"KEYPRESS"}]}'
  verify_ssl: false

Then the buttons use custom:button_card with templates. A TV template would be:

  bedroom_vizio:
    triggers_update: all
    variables:
      tv: bedroom_vizio
      ip: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'bedroom_vizio').ip ]]]
      port: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'bedroom_vizio').port ]]]
      auth: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'bedroom_vizio').auth ]]]
      clientaddr: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'bedroom_vizio').clientAddr ]]]

This is reading attributes for the IP, PORT, AUTH for the bedroom_vizio TV a sensor that reads that data from a JSON file I keep around with all the TV data, It also reads the CLIENTADDR which is a code for the DIrecTV box if you have Genie devices.

A snippet of this custom JSON file is like this (my auth and clientAddr is blocked out, you would need yours and also the proper IP address. For a Vizio, the port is likely 7345. As you can see, I also create a map of my favorite channels (on DIrecTV and a set of inputs or quick actions to get to DirecTV or Netflix or Hulu in one click):

{
    "tvs": [
        {
            "name": "patio_vizio",
            "ip": "192.168.2.90",
            "port": 7345,
            "auth": "************",
            "clientAddr": "**************",
            "favorites": [
                 {
                    "callsign": "ESPNHD",
                    "channel": 206
                },
                 {
                    "callsign": "ESPN2HD",
                    "channel": 209
                },
                {
                    "callsign": "NFLHD",
                    "channel": 202
                },
                 {
                    "callsign": "NFLHD",
                    "channel": 212
                },
                {
                    "callsign": "NHLHD",
                    "channel": 215
                },
                 {
                    "callsign": "MLBHD",
                    "channel": 213
                },
                {
                    "callsign": "NBAHD",
                    "channel": 216
                },
                 {
                    "callsign": "GolfHD",
                    "channel": 218
                },
                {
                    "callsign": "FS1HD",
                    "channel": 219
                },
                 {
                    "callsign": "NBCSHD",
                    "channel": 220
                },
                {
                    "callsign": "CBSSHND",
                    "channel": 221
                },
                 {
                    "callsign": "RedZone",
                    "channel": 702
                },
                {
                    "callsign": "BTNHD",
                    "channel": 610
                }
            ],
            "inputs": [
                {
                    "fname": "Power off",
                    "input": "Power off" 
                },
                 {
                    "fname": "DirecTV",
                    "input": "HDMI-1"
                },
                 {
                    "fname": "Smartcast",
                    "input": "CAST"
                },
                {
                    "fname": "Netflix",
                    "input": "Netflix"
                },
                 {
                    "fname": "HBOMax",
                    "input": "HBO Max"
                },
                {
                    "fname": "YouTube",
                    "input": "YouTube"
                },
                {
                    "fname": "Amazon Prime",
                    "input": "Prime"
                },
                {
                    "fname": "Hulu",
                    "input": "Hulu"
                },
                {
                    "fname": "AppleTV",
                    "input": "Apple TV"
                },
                {
                    "fname": "Discovery+",
                    "input": "discovery+"
                },
                {
                    "fname": "Disney+",
                    "input": "Disney+"
                },
                {
                    "fname": "Fox Now",
                    "input": "FOX NOW"
                }
            ]
        },

Then another button_card_template is used to create the actual action:

  vizio_action:
    variables:
      codeset: 4
      code: 3
    tap_action:
      action: call-service
      service: rest_command.vizio_processkey
      service_data:
        ip: '[[[ return variables.ip ]]]'
        port: '[[[ return variables.port ]]]'
        auth: '[[[ return variables.auth ]]]'
        codeset: '[[[ return variables.codeset ]]]'
        code: '[[[ return variables.code ]]]'

The IP and PORT and AUTH codes are stored in a JSON file. So at least you do not have to repeat all these things within the code of a button as that card supports templates which import.

Using the custom:button-card and templates totally simplifies things. Like this:

                - type: custom:button-card
                    icon: mdi:arrow-up-circle
                    template:
                      - icon_button
                      - bedroom_vizio
                      - vizio_action
                    variables:
                      codeset: 3
                      code: 8

So a button just needs to set the codeset and code. You could actually go further and do a lookup table and pass a variable like “up” but I did not go that far because I believe all Vizio’s have the same REST interface and it would save passing one variable (you would have a table that said “up” is codeset 3, code 8 … you would still pass “up”. Possibly that could be nice understanding though.

Putting that all together, that button is like clicking the “up arrow” on a remote. The TV would be the bedroom_vizio television (whose template gets the IP, PORT and AUTH code) and it sends codeset 3 and code 8 in the rest_command.

I am just starting to write this up and post all the code for both DIrecTV and Vizio but there are many things/assumptions in mine because of my setup. I also have Broadlink setup for a few TVs to do the volume because these are in old stereo recievers that have no interface except IR. But I will post it all for people to chop up as they desire.

1 Like

OK, I started posting on Git for those that care. I will post actual YAML files but most all of it is in the Readme

Most of the code is now there in separate files.

1 Like

Thanks for all this!! Youre awesome! Since YAML is easily changed to JSON, Im going to try and write my config in yaml. I have the rest_command.yaml as well, which definitely simplified things. I think a table lookup with the different codes would work, but it might be overcomplicating the issue in my case since I only have 1 vizio. In your case, you might be able to simplify it further, but it sounds like it works for you already and fixing what aint broke is probably ill-advised.

Again, I appreciate all youve done so far. I have a lot of code to write still, but this is a great start!! You made my understanding so much better, and I have really enjoyed coding this!

Note that in the code posted above I do not use Cycle anymore, I use an input_select and send directly the play_media command. Someone asked previously about this.