[SOLVED] Automate switching of Sony Bravia TV Scenes to change post-processing or picture mode for certain content

Edit: I got it working now, see below for the solution


So I’ve been trying to get the “Scenes” from my Sony Bravia so I can add them to an input_select list and change the scene of my Bravia. I’ve been able to change the scene as well as get the current scene from the API, but I’m having difficulties mapping the values from the json array of scenes.

This is the raw response from my TVs API:

JSON Response
{
  "id": 40,
  "result": [
    {
      "candidate": [
        {
          "value": "general"
        },
        {
          "value": "auto"
        },
        {
          "value": "auto24pSync"
        },
        {
          "value": "photo"
        },
        {
          "value": "music"
        },
        {
          "value": "cinema"
        },
        {
          "value": "game"
        },
        {
          "value": "graphics"
        },
        {
          "value": "sports"
        },
        {
          "value": "animation"
        }
      ],
      "currentValue": "game"
    }
  ]
}

And here are my configurations for accessing the TV API:

sensors.yaml
######### Sony Bravia KDL-55W805B ###########
############# Current Scene Sensor ##########
  - platform: rest
    name: Sony Bravia TV Power Status
    resource_template: !secret bravia_systemurl
    headers:
      x-auth-psk: !secret bravia_psk
    method: POST
    payload: '{"method":"getPowerStatus","params":[""],"id":1,"version":"1.0"}'
    value_template:  >
      {%- if value_json is defined -%}
        {{- value_json.result[0].status -}}
      {%- else -%}
        offline
      {%- endif -%}
    scan_interval: 5
############# Current Scene Sensor ##########
  - platform: rest
    name: Sony Bravia TV Current Scene
    resource_template: !secret bravia_videoscreenurl
    headers:
      x-auth-psk: !secret bravia_psk
    method: POST
    payload: '{"method":"getSceneSetting","params":[""],"id":40,"version":"1.0"}'
    value_template:  >
      {%- if value_json is defined -%}
        {{- value_json.result[0].currentValue -}}
      {%- else -%}
        auto
      {%- endif -%}
    scan_interval: 5
############# All Scenes Sensor #############
  - platform: rest
    name: Sony Bravia TV Scene Setting
    resource_template: !secret bravia_videoscreenurl
    headers:
      x-auth-psk: !secret bravia_psk
    method: POST
    payload: '{"method":"getSceneSetting","params":[""],"id":40,"version":"1.0"}'
    json_attributes_path: "$.result.[0]"
    json_attributes:
      - candidate
      - currentValue
    value_template:  'OK'
input_selects.yaml
  sony_bravia_tv_scenes:
    name: Sony Bravia TV Scenes
    icon: mdi:image-filter-hdr
    options: [ None ]
rest_commands.yaml
######### Sony Bravia KDL-55W805B ###########
############ Set Scene Command ##############
  sony_bravia_tv_set_scene_setting:
    url: 'http://{{ host }}/sony/videoScreen'
    method: POST
    headers:
      x-auth-psk: '{{ psk }}'
      accept: 'application/json'
    payload: '{"method":"setSceneSetting","params":[{"value":"{{ scene }}"}],"id":40,"version": "1.0" }'
    content_type:  'application/json; charset=utf-8'
############ Fill input command #############
  sony_bravia_tv_input_select_set_options:
    url: '{{ url }}/services/input_select/set_options'
    method: POST
    headers:
      authorization: 'Bearer {{ token }}'
      content-type: 'application/json'
    payload: >-
      {
        "entity_id": "input_select.sony_bravia_tv_scenes",
        "options": [
      {%- for item in state_attr("sensor.sony_bravia_tv_scene_setting", "candidate")|map(attribute="value")|list -%}
        "{{- item -}}"{% if not loop.last %}, {% endif %}
      {%- endfor -%}
        ]
      }
automations.yaml
######### Sony Bravia KDL-55W805B ###########
####### Automation to disable automations when TV is off #######
  - alias: Sony Bravia TV Automations
    initial_state: 'off'
    trigger:
      - platform: state
        entity_id: sensor.sony_bravia_tv_power_status
        to: 'standby'
      - platform: state
        entity_id: sensor.sony_bravia_tv_power_status
        to: 'offline'
    action:
      # Turn off automations
      - service: automation.turn_off
        data:
          entity_id: automation.sony_bravia_tv_input_select_scene_set
      - service: automation.turn_off
        data:
          entity_id: automation.sony_bravia_tv_input_select_current_scene_populator
      - service: input_select.set_options
        data_template:
          entity_id: input_select.sony_bravia_tv_scenes
          options: [ 'None' ]
####### Automation to query scenes from Sony Bravia TV for input select #######
  - alias: Sony Bravia TV Input Select Scenes Populator
    initial_state: 'on'
    trigger:
      - platform: homeassistant
        event: start
      - platform: state
        entity_id: sensor.sony_bravia_tv_power_status
        to: 'active'
    action:
      # Turn off other automations
      - service: automation.turn_off
        data:
          entity_id: automation.sony_bravia_tv_input_select_scene_set
      - service: automation.turn_off
        data:
          entity_id: automation.sony_bravia_tv_input_select_current_scene_populator
      # Fill input_select.sony_bravia_tv_scenes with all available scenes
      - service: rest_command.sony_bravia_tv_input_select_set_options
        data:
          url: !secret internal_api_url
          token: !secret internal_api_token
      - service: input_select.select_option
        data_template:
          entity_id: input_select.sony_bravia_tv_scenes
          option: '{{ states("sensor.sony_bravia_tv_current_scene") }}'
      # Turn other automations on again
      - service: automation.turn_on
        data:
          entity_id: automation.sony_bravia_tv_input_select_scene_set
      - service: automation.turn_on
        data:
          entity_id: automation.sony_bravia_tv_input_select_current_scene_populator
      - service: automation.turn_on
        data:
          entity_id: automation.sony_bravia_tv_automations
####### Automation for sending the selected scene to Sony Bravia TV #######
  - alias: Sony Bravia TV Input Select Scene Set
    initial_state: 'off'
    trigger:
      - platform: state
        entity_id: input_select.sony_bravia_tv_scenes
    action:
      - service: rest_command.sony_bravia_tv_set_scene_setting
        data_template:
          host: !secret bravia_host
          psk: !secret bravia_psk
          scene: '{{ states("input_select.sony_bravia_tv_scenes") }}'
####### Automation to query current scene from Sony Bravia TV for input select #######
  - alias: Sony Bravia TV Input Select Current Scene Populator
    initial_state: 'off'
    trigger:
      - platform: state
        entity_id: sensor.sony_bravia_tv_current_scene
    action:
      - service: automation.turn_off
        data:
          entity_id: automation.sony_bravia_tv_input_select_scene_set
      - service: input_select.select_option
        data_template:
          entity_id: input_select.sony_bravia_tv_scenes
          option: '{{ states("sensor.sony_bravia_tv_current_scene") }}'
      - service: automation.turn_on
        data:
          entity_id: automation.sony_bravia_tv_input_select_scene_set
media_players.yaml
  - platform: braviatv
    name: Sony Bravia KDL-55W805B
    host: !secret bravia_host
secrets.yaml
bravia_host: '192.168.0.200' # this is your bravias ip
bravia_psk: '0000' # this is your bravias psk (set it within "Network Settings" on the TV)
bravia_videoscreenurl: 'http://192.168.100.49/sony/videoScreen' # this is the api url to get tv scenes, insert your bravias ip here
bravia_systemurl: 'http://192.168.100.49/sony/system' # this is the api url to get tv power state, insert your bravias ip here
internal_api_url: 'http://hass.example.com:8123/api' # make sure this url points to your hass api  otherwise it will result in 401 and 403 errors
internal_api_token: '<your token>' # generate a new long lived token in your profile settings
configuration.yaml
# enable api
api:

automation: !include automations.yaml
sensor: !include sensors.yaml
media_player: !include media_players.yaml
rest_command: !include rest_commands.yaml
input_select: !include input_selects.yaml

This configuration basically pulls the available scenes from the TVs API including the currently set scene of the TV. The “Sony Bravia TV Current Scene” sensor pulls the current scene from the API every 5 seconds. If the value has changed (when you manually change it with your remote for example) it will update the current option of the input_select to the current value of the API response. If you select a scene in the input_select it will send the new value to the TV updating the scene.
I wrote this automation so I can turn off the post processing when I want to play games on the TV.

This can be combined for stuff like changing the scene to game when your AVR or TV changes to a gaming console input, effectively reducing the post processing of the TV. Or if you want to watch anime it can change to animation or cinema when watching Netflix.

I also implemented a better state detection for the TVs on/off state via API since the media_player for Bravias isn’t as fast and isn’t implementing API calls properly.

I can confirm that this is working for my Sony Bravia KDL-55W805B, but if the API didn’t change it should effectively work for most Sony Bravia models released after 2013. I can’t guarantee it of course, you have to look through the API yourself.

Here are some useful resources for getting info on your Bravias API:
https://pro-bravia.sony.net/develop/integrate/rest-api/spec/index.html

3 Likes

Love this idea. I have a 2018 model. It has a picutremode and a picture setting.
With this setup I can only select the setting which are (from the sensor)

candidate: 
- value: auto
- value: auto24pSync
- value: general

currentValue: general
friendly_name: Sony Bravia TV Scene Setting

Need to figure out how to get to the mode for my tv. If I figure it out I’ll let you know

I’m trying to figure out how to change the “Picture” Mode so I can try to automate automatic switching when I play my Playstation vs Watching content through my Nvidia shield.

I’m trying to follow what’s going on in this post but a little lost. “Scene” isnt’ something I was familiar with, as mine is always “general” and Im not seeing picture mode.

e.g. this is what I see after setting up the sensors and such described in this thread:

This was still “general” even when I had my TV set to “Game” picture mode. Help?

I recently set up Home Assistant and am trying to make Home Assistant change my Sony Bravia TV’s picture mode to “game” mode whenever I launch a game on my Xbox One using the Xbox integration, and change it to one of the other picture modes when I, for example, launch Netflix. I’d like to implement whatever is listed here that works, but I do not understand what has been written. Can someone please explain it to me as if I am five years old? I’ve cloned this GitHub repository and have some experience with batch scripting, but I have no idea what to do with the code shown in this thread. I’m only getting familiar with Home Assistant.

Thanks for the work @shawly. As the above replies mentioned the videoScreen API does not look look to have additional picture mode settings nested within the scenes (general/auto/auto24pSync) on newer TV models. I’m not sure if this is backwards compatible with older models. I’ve tested this on a XBR-65A8H.

I spent some time familiarizing myself with the API and have found that we can still get and set pictureMode properly using the video API (not videoScreen) and getPictureQualitySettings/setPictureQualitySettings (API:getPictureQualitySettings).

Here’s my setup using a package instead. The only YAML code needing updates is secrets.yaml to match your network details. The rest should work without modification. You need to create a packages folder within your base directory (where configuration.yaml sits) if it does not already exist.

configuration.yaml
# add this to your configuration.yaml
homeassistant:
  packages: !include_dir_named packages

secrets.yaml
# Use this file to store secrets like usernames and passwords. 
# Learn more at https://www.home-assistant.io/docs/configuration/secrets/ 
bravia_host: '192.168.1.160' # this is your bravias ip 
bravia_psk: '0000' # this is your bravias psk (set it within "Network Settings" on the TV) 
bravia_videoscreenurl: 'http://192.168.1.160/sony/video' # this is the api url to get tv scenes, insert your bravias ip here 
bravia_systemurl: 'http://192.168.1.160/sony/system' # this is the api url to get tv power state, insert your bravias ip here 
internal_api_url: 'http://192.168.1.158:8123/api' # make sure this url points to your hass api otherwise it will result in 401 and 403 errors
internal_api_token: '' # generate a new long lived token in your profile settings

packages/bravia_package.yaml
automation:
  - id: 'bravia.automations'
    alias: Sony Bravia TV Automations
    initial_state: 'off'
    trigger:
      - platform: state
        entity_id: sensor.sony_bravia_tv_power_status
        to: 'standby'
      - platform: state
        entity_id: sensor.sony_bravia_tv_power_status
        to: 'offline'
    action:
      # Turn off automations
      - service: automation.turn_off
        data:
          entity_id: automation.sony_bravia_tv_input_select_scene_set
      - service: automation.turn_off
        data:
          entity_id: automation.sony_bravia_tv_input_select_current_scene_populator
      - service: input_select.set_options
        data_template:
          entity_id: input_select.sony_bravia_tv_scenes
          options: [ 'None' ]
  - id: 'bravia.scene.populator'
    alias: Sony Bravia TV Input Select Scenes Populator
    initial_state: 'on'
    trigger:
      - platform: homeassistant
        event: start
      - platform: state
        entity_id: sensor.sony_bravia_tv_power_status
        to: 'active'
    action:
      # Turn off other automations
      - service: automation.turn_off
        data:
          entity_id: automation.sony_bravia_tv_input_select_scene_set
      - service: automation.turn_off
        data:
          entity_id: automation.sony_bravia_tv_input_select_current_scene_populator
      # Fill input_select.sony_bravia_tv_scenes with all available scenes
      - service: rest_command.sony_bravia_tv_input_select_set_options
        data:
          url: !secret internal_api_url
          token: !secret internal_api_token
      - service: input_select.select_option
        data_template:
          entity_id: input_select.sony_bravia_tv_scenes
          option: '{{ states("sensor.sony_bravia_tv_current_scene") }}'
      # Turn other automations on again
      - service: automation.turn_on
        data:
          entity_id: automation.sony_bravia_tv_input_select_scene_set
      - service: automation.turn_on
        data:
          entity_id: automation.sony_bravia_tv_input_select_current_scene_populator
      - service: automation.turn_on
        data:
          entity_id: automation.sony_bravia_tv_automations
  - id: 'bravia.scene.set'
    alias: Sony Bravia TV Input Select Scene Set
    initial_state: 'off'
    trigger:
      - platform: state
        entity_id: input_select.sony_bravia_tv_scenes
    action:
      - service: rest_command.sony_bravia_tv_set_scene_setting
        data_template:
          host: !secret bravia_host
          psk: !secret bravia_psk
          scene: '{{ states("input_select.sony_bravia_tv_scenes") }}'
  - id: 'bravia.input.select'
    alias: Sony Bravia TV Input Select Current Scene Populator
    initial_state: 'off'
    trigger:
      - platform: state
        entity_id: sensor.sony_bravia_tv_current_scene
    action:
      - service: automation.turn_off
        data:
          entity_id: automation.sony_bravia_tv_input_select_scene_set
      - service: input_select.select_option
        data_template:
          entity_id: input_select.sony_bravia_tv_scenes
          option: '{{ states("sensor.sony_bravia_tv_current_scene") }}'
      - service: automation.turn_on
        data:
          entity_id: automation.sony_bravia_tv_input_select_scene_set
sensor:
  - platform: rest
    name: Sony Bravia TV Power Status
    resource_template: !secret bravia_systemurl
    headers:
      x-auth-psk: !secret bravia_psk
    method: POST
    payload: '{"method":"getPowerStatus","params":[""],"id":1,"version":"1.0"}'
    value_template:  >
      {%- if value_json is defined -%}
        {{- value_json.result[0].status -}}
      {%- else -%}
        offline
      {%- endif -%}
    scan_interval: 5
  - platform: rest
    name: Sony Bravia TV Current Scene
    resource_template: !secret bravia_videoscreenurl
    headers:
      x-auth-psk: !secret bravia_psk
    method: POST
    payload: '{"method":"getPictureQualitySettings","params":[{"target":"pictureMode"}],"id":52,"version":"1.0"}'
    value_template:  >
      {%- if value_json is defined -%}
        {{- value_json.result[0][0].currentValue -}}
      {%- else -%}
        auto
      {%- endif -%}
    scan_interval: 5
  - platform: rest
    name: Sony Bravia TV Scene Setting
    resource_template: !secret bravia_videoscreenurl
    headers:
      x-auth-psk: !secret bravia_psk
    method: POST
    payload: '{"method":"getPictureQualitySettings","params":[{"target":"pictureMode"}],"id":52,"version":"1.0"}'
    json_attributes_path: "$.result.[0][0]"
    json_attributes:
      - candidate
      - currentValue
    value_template:  'OK'
input_select:
  sony_bravia_tv_scenes:
    name: Sony Bravia TV Scenes
    icon: mdi:image-filter-hdr
    options: [ None ]
rest_command:
  sony_bravia_tv_set_scene_setting:
    url: 'http://{{ host }}/sony/video'
    method: POST
    headers:
      x-auth-psk: '{{ psk }}'
      accept: 'application/json'
    payload: '{"method":"setPictureQualitySettings","params":[{"settings":[{"target":"pictureMode","value":"{{ scene }}"}]}],"id":40,"version": "1.0" }'
    content_type:  'application/json; charset=utf-8'
  sony_bravia_tv_input_select_set_options:
    url: '{{ url }}/services/input_select/set_options'
    method: POST
    headers:
      authorization: 'Bearer {{ token }}'
      content-type: 'application/json'
    payload: >-
      {
        "entity_id": "input_select.sony_bravia_tv_scenes",
        "options": [
      {%- for item in state_attr("sensor.sony_bravia_tv_scene_setting", "candidate")|map(attribute="value")|list -%}
        "{{- item -}}"{% if not loop.last %}, {% endif %}
      {%- endfor -%}
        ]
      }
media_player:
  - platform: braviatv
    name: Sony Bravia KDL-55W805B
    host: !secret bravia_host

Reload your configuration or reset your HomeAssistant server to find the new scene/sensors which you can then use in your own Automations.

Here’s two of my examples using the new additions, available via input_select.select_option:

automations.yaml
- id: '1643408701430'
  alias: TV Picture Mode Game
  description: ''
  trigger:
  - platform: state
    entity_id: media_player.living_shield_2
    attribute: app_name
    to:
      - s0undTV
      - com.nvidia.tegrazone3
  condition: []
  action:
  - service: input_select.select_option
    target:
      entity_id: input_select.sony_bravia_tv_scenes
    data:
      option: game
  mode: single
- id: '1643408746667'
  alias: TV Picture Mode Custom
  description: ''
  trigger:
  - platform: state
    entity_id: media_player.living_shield_2
    attribute: app_name
    from:
      - s0undTV
      - com.nvidia.tegrazone3
  condition: []
  action:
  - service: input_select.select_option
    target:
      entity_id: input_select.sony_bravia_tv_scenes
    data:
      option: custom
  mode: single

1 Like

If you added the services listed above, you can use this code in YAML:

service: rest_command.sony_bravia_tv_set_scene_setting
data:
  scene: custom

Just change custom with any picture mode you want

Hey Devin. Like this thank you! I want to automate changing pictureMode from Vivid to Standard. Will this allow that? I tried the following and get an error 404 on my TV but other URL’s that use /sony/system work just fine.

FYI, my TV is a KD-55X8500D

http://ip.address.ofmy.tv/sony/video

{
    "method": "getPictureQualitySettings",
    "id": 52,
    "params": [{
        "target": "color"
    }],
    "version": "1.0"
}

Response:
{
    "error": [
        404,
        "Not Found"
    ]
}

[EDIT] Hmmm. Seems /sony/video is no longer supported?? TV Device Interface - v5.0.0 | BRAVIA Professional Displays Knowledge Center

Hi xbmcnut,

I have recently found a solution to this. Setting up a REST command in configuration.yaml will allow you to set specific picture modes remotely by triggering the service in HASS. Change the url and psk (needs to be set up in TV’s network settings) to suit your setup. Also set desired picture mode via “value”.

rest_command:
  sony_bravia_custom:
    url: "http://192.168.1.1/sony/video"
    method: POST
    headers:
      x-auth-psk: "1111"
      accept: "application/json"
    payload: '{"method": "setPictureQualitySettings","id": 3,"params": [{"settings": [{"value": "custom","target": "pictureMode"}]}],"version": "1.0"}'
    content_type: "application/json; charset=utf-8"

Picture mode values reported by my tv are:

{"value":"vivid"},{"value":"standard"},{"value":"cinema"},{"value":"game"},{"value":"graphics"},{"value":"photo"},{"value":"custom"},{"value":"customForPro1"},{"value":"customForPro2"},{"value":"imax"},{"value":"dvDark"},{"value":"dvBright"},{"value":"dvVivid"}

Additionally you may also change the target if you with to change brightness for example. More info can be found here: getPictureQualitySettings (v1.0) | BRAVIA Professional Displays Knowledge Center

All the best!

1 Like

Thanks for the reply but sadly my TV is a 2016 model and it doesn’t support any functions sent to

http://baseurl/sony/video