Vizio TV Integration

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.

Does anyones Vizio tv turn itself on in the middle of the night for 8 second or so? I assume maybe it’s doing some kind of nightly update, but if true it’s too bad it causes state change.

Home assistant sees the state change while everyone is asleep. My automation then runs turning all the lights on.

I have not seen that. I have 4 Vizio TVs but I did not comb through history. I do not have any automation based on the state though, I have automations for remotes, but these are all triggered on a state change of an input_select and not on the status of the TV itself.

Thanks! If you check your history tab and filter for Vizio media player you might be able to see it.

I suppose it’s possible that it’s CEC connected device like google Chromecast or firestick 4k doing a nightly update causing that. However I didn’t notice the same behaviour on a Roku TV.

Just an update for anyone using this, I just noticed that a recent update to the Vizio TV changed the name of the source from “Prime” to “Prime Video”. Simple change in the JSON file that contains the inputs is required to send the select_source command as “Prime Video”:

                {
                    "fname": "Amazon Prime",
                    "input": "Prime Video"
                },

And another gotcha. I posted an issue to the Vizio integration as it seems something has broke selecting inputs like HDMI-1. See Vizio Smartcast Integration cannot use media_player select source for anything not a TV "app" · Issue #83689 · home-assistant/core · GitHub

Asking here, has anyone else seen this issue I have posted? You can simply test by using Developer Tools and calling the media_player.select_source passing in something like ‘HDMI-1’. To recap, Vizio downloaded an upgrade into newer TVs and this functionality in HA broke. I am trying to get someone to look at it but no activity. If you do have this issue, I suggest posting a “me too” message here on Github:

UPDATE

I have diagnosed the issue. More information at the end of that link abve. Now it’s up to the programmers to fix. The issue for newer TVs is that it uses “hdmi1” and not “HDMI-1” and so forth. However, you cannot just send “hdmi1” as that does not work deep in the code. It expects a valid source and the source for Vizio media players is “HDMI-1”. So whomever is the author needs to make mods in the Vizio integration to recognize these.

1 Like

I’m running into this issue as well. It looks like it would be an update to PyVizio, which would then need a a release, and then it would need to get pulled into HA.

While I don’t have the skills to do that at the moment, I might give it a shot in future.

In the meanwhile, do you have a workaround for selecting a source?

Unfortunately not. It was also on my list to do. It is a bit annoying but in reality we work around it by selecting a different source and then going back and most times that works.

Also in some cases if you are on something and select DirecTV (HDMI-1 for me) then it sits there BUT if you then hit guide in our remote GUI it jumps to DirecTV.

By the way, this code has numerous issues as I can see, not the least of which is that whoever wrote it relies on connection to app ids from: http://hometest.buddytv.netdna-cdn.com/appservice/vizio_apps_prod.json

Which does not exist. So i would guess that it uses a default set and there are several APPs that do not exist in that standard set (it is WAY old). That could be easiest at first to tackle. My TV shows these … note no HBOMax, No Discover+, No FoxNow …

source_list:
  - HDMI-1
  - HDMI-2
  - HDMI-3
  - COMP
  - TV
  - Prime Video
  - CBS All Access
  - CBS News
  - Crackle
  - Curiosity Stream
  - Fandango Now
  - FilmRise
  - Flixfling
  - Haystack TV
  - Hulu
  - iHeartRadio
  - NBC
  - Netflix
  - Plex
  - Pluto TV
  - RedBox
  - TasteIt
  - Toon Goggles
  - Vudu
  - XUMO
  - YouTubeTV
  - YouTube
  - Baeble
  - DAZN
  - FitFusion by Jillian Michaels
  - Newsy
  - Cocoro TV
  - ConTV
  - Dove Channel
  - Love Destination
  - WatchFree
  - AsianCrush
  - Disney+

Now, taking this: pyvizio/const.py at bddb6381a50249c5c228037522c739fe9d10aa8a · vkorn/pyvizio · GitHub

Carving out the apps and fixing the horrible JSON that was written (by horrible I mean it relies on relaxed JSON rules allowing commas to be at the end with nothing following and no one should ever do that), I can get a list of names built in:

33 of them:

Which is the list of Apps reported in the interface.
So …

  1. That entire JSON needs to be redone correctly
  2. new Apps need to be added and stuffed into that code as it is obviously using that list. That would get us modern apps like HBOMax
  3. That should be moved and all references to this mysterious buddytv non-existant JSON file removed

Once that is done at least we should get all the apps. I just wish there was some place to go get them, not sure where because it need for any one app:

    {
        "name": "Netflix",
        "country": ["*"],
        "id": ["34"],
        "config": [
            {
                "NAME_SPACE": 3,
                "APP_ID": "1",
                "MESSAGE": "None"
            }
        ]
    }

After that, the “HDMI-1” versus 'hdmi1" and cast and such can be addressed.

By the way, this is what the current APPS are as a constant in the Python code:

[
    {
        "name": "Prime Video",
        "country": ["*"],
        "id": ["33"],
        "config": [
            {
                "APP_ID": "4",
                "NAME_SPACE": 4,
                "MESSAGE": "https://atv-ext.amazon.com/blast-app-hosting/html5/index.html?deviceTypeID=A3OI4IHTNZQWDD"
            },
            {"NAME_SPACE": 2, "APP_ID": "4", "MESSAGE": "None"}
        ]
    },
    {
        "name": "CBS All Access",
        "country": ["usa"],
        "id": ["9"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "37",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "CBS News",
        "country": [
            "usa",
            "can"
        ],
        "id": ["56"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "42",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Crackle",
        "country": ["usa"],
        "id": ["8"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "5",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Curiosity Stream",
        "country": [
            "usa",
            "can"
        ],
        "id": ["37"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "12",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Fandango Now",
        "country": ["usa"],
        "id": ["24"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "7",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "FilmRise",
        "country": ["usa"],
        "id": ["47"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "24",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Flixfling",
        "country": ["*"],
        "id": ["49"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "36",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Haystack TV",
        "country": [
            "usa",
            "can"
        ],
        "id": ["35"],
        "config": [
            {
                "NAME_SPACE": 0,
                "APP_ID": "898AF734",
                "MESSAGE": "{\"CAST_NAMESPACE\":\"urn:x-cast:com.google.cast.media\",\"CAST_MESSAGE\":{\"type\":\"LOAD\",\"media\":{},\"autoplay\":true,\"currentTime\":0,\"customData\":{\"platform\":\"sctv\"}}}"
            }
        ]
    },
    {
        "name": "Hulu",
        "country": ["usa"],
        "id": ["19"],
        "config": [
            {
                "APP_ID": "3",
                "NAME_SPACE": 4,
                "MESSAGE": "https://viziosmartcast.app.hulu.com/livingroom/viziosmartcast/1/index.html#initialize"
            },
            {
                "NAME_SPACE": 2,
                "APP_ID": "3",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "iHeartRadio",
        "country": ["usa"],
        "id": ["11"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "6",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "NBC",
        "country": ["usa"],
        "id": ["43"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "10",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Netflix",
        "country": ["*"],
        "id": ["34"],
        "config": [
            {
                "NAME_SPACE": 3,
                "APP_ID": "1",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Plex",
        "country": [
            "usa",
            "can"
        ],
        "id": ["40"],
        "config": [
            {
                "APP_ID": "9",
                "NAME_SPACE": 4,
                "MESSAGE": "https://plex.tv/web/tv/vizio-smartcast"
            },
            {
                "NAME_SPACE": 2,
                "APP_ID": "9",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Pluto TV",
        "country": ["usa"],
        "id": ["12"],
        "config": [
            {
                "APP_ID": "65",
                "NAME_SPACE": 4,
                "MESSAGE": "https://smartcast.pluto.tv"
            },
            {
                "NAME_SPACE": 0,
                "APP_ID": "E6F74C01",
                "MESSAGE": "{\"CAST_NAMESPACE\":\"urn:x-cast:tv.pluto\",\"CAST_MESSAGE\":{\"command\":\"initializePlayback\",\"channel\":\"\",\"episode\":\"\",\"time\":0}}"
            }
        ]
    },
    {
        "name": "RedBox",
        "country": ["usa"],
        "id": ["55"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "41",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "TasteIt",
        "country": ["*"],
        "id": ["52"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "26",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Toon Goggles",
        "country": [
            "usa",
            "can"
        ],
        "id": ["46"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "21",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Vudu",
        "country": ["usa"],
        "id": ["6"],
        "config": [
            {
                "APP_ID": "31",
                "NAME_SPACE": 4,
                "MESSAGE": "https://my.vudu.com/castReceiver/index.html?launch-source=app-icon"
            }
        ]
    },
    {
        "name": "XUMO",
        "country": ["usa"],
        "id": ["27"],
        "config": [
            {
                "NAME_SPACE": 0,
                "APP_ID": "36E1EA1F",
                "MESSAGE": "{\"CAST_NAMESPACE\":\"urn:x-cast:com.google.cast.media\",\"CAST_MESSAGE\":{\"type\":\"LOAD\",\"media\":{},\"autoplay\":true,\"currentTime\":0,\"customData\":{}}}"
            }
        ]
    },
    {
        "name": "YouTubeTV",
        "country": [
            "usa",
            "mexico"
        ],
        "id": ["45"],
        "config": [
            {
                "NAME_SPACE": 5,
                "APP_ID": "3",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "YouTube",
        "country": ["*"],
        "id": ["44"],
        "config": [
            {
                "NAME_SPACE": 5,
                "APP_ID": "1",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Baeble",
        "country": ["usa"],
        "id": ["39"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "11",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "DAZN",
        "country": [
            "usa",
            "can"
        ],
        "id": ["57"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "34",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "FitFusion by Jillian Michaels",
        "country": [
            "usa",
            "can"
        ],
        "id": ["54"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "39",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Newsy",
        "country": [
            "usa",
            "can"
        ],
        "id": ["38"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "15",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Cocoro TV",
        "country": [
            "usa",
            "can"
        ],
        "id": ["63"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "55",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "ConTV",
        "country": [
            "usa",
            "can"
        ],
        "id": ["41"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "18",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Dove Channel",
        "country": [
            "usa",
            "can"
        ],
        "id": ["42"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "16",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "Love Destination",
        "country": ["*"],
        "id": ["64"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "57",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "WatchFree",
        "country": ["usa"],
        "id": ["48"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "22",
                "MESSAGE": "None"
            }
        ]
    },
    {
        "name": "AsianCrush",
        "country": [
            "usa",
            "can"
        ],
        "id": ["50"],
        "config": [
            {
                "NAME_SPACE": 2,
                "APP_ID": "27",
                "MESSAGE": "https://html5.asiancrush.com/?ua=viziosmartcast"
            }
        ]
    },
    {
        "name": "Disney+",
        "country": ["usa"],
        "id": ["51"],
        "config": [
            {
                "NAME_SPACE": 4,
                "APP_ID": "75",
                "MESSAGE": "https://cd-dmgz.bamgrid.com/bbd/vizio_tv/index.html"
            }
        ]
    }
]

UPDATE:

I know how to get information for the apps I think. If you take your TV and navigate to say HBOMax and then get the state you see this:

image

As you can see it is _UNKNOWN_APP because it is not in the list, yet it shows all the information needed to be “in the list” if added. the APP_ID, namespace and message. It is unclear to me though what the other “id” is at the root level.

UPDATE:

I have now created a GIT at GitHub - kbrown01/VizioApps: Set of JSON files for modern VIZIO TVs with the APPs for Home Assistant integrations

This has about 100 APPs as of now.
I also changed the pyvizio code in util/const.py to point at these URLs from GIT and it works perfect.

In my setup right now, I can do this:

{{ state_attr('media_player.office_vizio','source_list') }}

And I get this:

[
  "HDMI-1",
  "HDMI-2",
  "HDMI-3",
  "COMP",
  "TV",
  "AMC+",
  "Acorn TV",
  "Adventure 2 Learning",
  "Amazon Music",
  "Apple TV",
  "AsianCrush",
  "BET+",
  "Blackdove",
  "Brown Sugar",
  "CBS News",
  "CBS Sports",
  "Canela.TV",
  "Chicken Soup",
  "Christmas Plus",
  "Cocoro TV",
  "ConTV",
  "Coronavirus.gov",
  "Court TV",
  "Crackle",
  "Curiosity Stream",
  "DAZN",
  "Dark Matter TV",
  "Discovery Go",
  "Disney+",
  "Dove Channel",
  "ET Live",
  "Electric Now",
  "FOX NOW",
  "FOX Sports",
  "FilmRise",
  "FilmRise Action",
  "FilmRise Black TV",
  "FilmRise British TV",
  "FilmRise Western",
  "Fite TV",
  "Flixfling",
  "Food Network Go",
  "Fox Nation: Celebrate America",
  "Free Games by PlayWorks",
  "Free Movies+",
  "Funimation",
  "HBO Max",
  "HGTV Go",
  "HappyKids.tv",
  "HaystackNews",
  "Here TV",
  "Home Talk TV",
  "Hulu",
  "ID Go",
  "Journy",
  "Jungo+",
  "Kidoodle",
  "Lifetime Movie Club",
  "Local Now",
  "Loop",
  "Love Destination",
  "Made It Myself",
  "MagellanTV",
  "Movies Anywhere",
  "Movies By Fawesome",
  "Movies Now",
  "NBC",
  "Netflix",
  "Newsy",
  "Ninja Kidz TV",
  "PBS Kids",
  "Pandora",
  "Paramount+",
  "Party Tyme Karaoke",
  "Peacock",
  "Phoenix TV",
  "Plex",
  "Pluto TV",
  "Prime Video",
  "RedBox",
  "RetroCrush",
  "Row8",
  "Sanctuary Yoga",
  "Sesame Street",
  "SiriusXM",
  "Sling",
  "Starz",
  "TLC Go",
  "The Archive",
  "The CW",
  "The Daily Wire",
  "Tidal",
  "TikTok",
  "Toon Goggles",
  "TubiTV",
  "Vevo",
  "Vudu",
  "WatchFree",
  "Wu Tang",
  "XUMO",
  "YouTube",
  "YouTubeTV",
  "YuyuTV",
  "iHeartRadio"
]

UPDATE: The JSON files are finished if anyone cares. You can use the JSON files directly from Github to be able to access all 154 Apps on a modern (at least my) Vizio TVs.

@anthonylavado … I would note that I did solve my issue somewhat. I created a shell command like this:

vizio_directv: >
    curl -k -H "Content-Type: application/json" -H "AUTH: {{auth}}" -X PUT -d '{"REQUEST": "MODIFY","VALUE": "hdmi1","HASHVAL": 2023834057}' https://{{ip}}:{{port}}/menu_native/dynamic/tv_settings/devices/current_input
  

Calling this command with the AUTH, IP and PORT of your TV will switch it to “hdmi1” (and NOT HDMI-1 as the code does). I just use a fixed value for HASHVAL as on my TV that is always the HASHVAL when it is in CAST. Thus instead of select source, call this command service and it will switch.

I can do this because I am not switching between say “hdmi2” to “hdmi1”. For that you would need to get the current HASHVAL and then use that in a second call to change it. I though of creating sensors that constantly got the HASHVAL and stored it and just use it in the template, but it seemed like too much work in hopes someone would do something with pvvizio sooner.