Skip to content

Instantly share code, notes, and snippets.

@wmealing
Forked from kalleth/sony_bravia.md
Created July 18, 2022 11:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wmealing/7d2b579df68c96eb09ba3401a46f0666 to your computer and use it in GitHub Desktop.
Save wmealing/7d2b579df68c96eb09ba3401a46f0666 to your computer and use it in GitHub Desktop.

Sony Bravia HTTP API

The sony bravia has a HTTP API interacted with using a Pre-Shared key. There's a more complex auth flow but I've not described it here.

There wasn't any documentation, so I've written some. If you're a TV integrator don't read this, you'll laugh. I'm probably just getting confused by UPnP.

Disclaimer: I've only tested this on my TV, which is a KDL-50W829B. Your TV might not have all of the services; see Available services section for how to discover what your TV supports.

Sources

Powering the TV on

  • Enable 'Wake on LAN' in the TV options (Settings -> Network -> Home Network Setup -> Remote Start (switch on)

  • Send a Wake on LAN packet to the TV using standard methods, e.g.:

    wakeonlan -i 192.168.0.98 FC:F1:de:ad:b3:3f

Interacting with the HTTP API

Send POST requests, with a JSON payload. An example (to list the Methods available to be called against the 'system' service) is:

curl -H "Content-Type: application/json" \
  -X POST \
  -d '{"id": 20, "method": "getMethodTypes", "version": "1.0", "params": [""]}' \
  http://192.168.0.98/sony/system

To send authenticated requests, set a "pre-shared" key, by visiting Settings -> Network -> Home Network Setup -> IP Control -> Pre-Shared Key. Say mine was 'pass123'.

curl -H "Content-Type: application/json" \
  -H "X-Auth-PSK: pass123" \
  -X POST \
  -d '{"id": 20, "method": "PowerOff", "version": "1.0", "params": []}' \
  http://192.168.0.98/sony/system

For brevity's sake, I'll only give the endpoint, JSON, and if it's communicated, on other endpoints.

Available services (endpoints)

The TV has a file called 'dmr.xml' (a upnp.org schema) made available at http://192.168.0.98:52323/dmr.xml -- useful for determining the following endpoints exist on my TV:

  • /sony/IRCC
  • /sony/accessControl
  • /sony/appControl
  • /sony/avContent
  • /sony/browser
  • /sony/cec
  • /sony/encryption
  • /sony/guide
  • /sony/notification
  • /sony/recording
  • /sony/system
  • /sony/videoScreen

For each service, you can use the getVersions or getMethodTypes methods to explore which methods are available on that service.

A precis of what's supported for these services is given below:

IRCC /sony/IRCC

Authenticated endpoint. SOAP interaction. Suspect this is the main entrypoint for upnp systems?

Interacting with this service allows you to "fake" buttons being pressed on the remote. This is how the bravia npm library controls the TV.

You send this endpoint a single remote controller code -- available from the system endpoints getRemoteControllerInfo method, and it will execute it as if you pressed it on your TV remote.

For reasons passing understanding (there's probably a standard for this...somewhere), you interact with this endpoint as SOAP rather than JSON, sending it this payload:

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
    <u:X_SendIRCC xmlns:u="urn:schemas-sony-com:service:IRCC:1">
        <IRCCCode><IRCC-COMMAND></IRCCCode>
    </u:X_SendIRCC>
</s:Body>
</s:Envelope>

For example, to power it off, use this curl command:

curl -H "Content-Type: application/json" \
  -X POST \
  -H "X-Auth-PSK: pass123" \
  -d '<?xml version="1.0" encoding="utf-8"?>
  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
      <u:X_SendIRCC xmlns:u="urn:schemas-sony-com:service:IRCC:1">
          <IRCCCode>AAAAAQAAAAEAAAAvAw=</IRCCCode>
      </u:X_SendIRCC>
  </s:Body>
  </s:Envelope>' \
  http://192.168.0.98/sony/IRCC

There appears to be additional information at http://192.168.0.98:52323/IRCCSCPD.xml which describes an additional X_GetStatus request you can use with the IRCC endpoint, providing a category code.

Access Control /sony/accessControl

App Control /sony/appControl

AV Content /sony/avContent

Method: deleteContent

versions: [1.0] params

{ "uri": "string" }

empty response

Method: getContentCount

versions: [1.0] params

{
  "source": "string",
  "type": "string",
  "count": int
}

response

{
  "count": int
}

Method: getContentList

versions: [1.0] params

{
  "source": "string",
  "type": "string",
  "stIdx": int,
  "cnt": int,
  "type": "string",
}

response

{
  "uri": "string",
  "title": "string",
  "index": "int",
  "dispNum": "string",
  "originalDispNum": "string",
  "tripletStr": "string",
  "programNum": "int",
  "programMediaType": "string",
  "startDateTime": "string",
  "durationSec": "int",
  "channelName": "string",
  "isProtected": "bool",
  "directRemoteNum": "int",
  "isAlreadyPlayed": "bool"
}

Method: getCurrentExternalInputsStatus

versions: [1.0] params

{} //empty input

response

[
  {
    "title": "string",
    "uri": "string",
    "connection": "bool",
    "label": "string",
    "icon": "string"
  }
]

purpose

Lists your "Inputs" on your TV, with their connection status -- it knows if
they're connected or not -- providing their title that you gave them on the
TV. Also provides a URI to identify them, to be used in <WHERE?>

Method: getMethodTypes

versions: [1.0] standard to all services

Method: getParentalRatingSettings

versions: [1.0] params

{} //empty input

response

{
  "ratingCountry": "string",
  "ratingTypeAge": "integer",
  "ratingTypeSony": "string",
  "ratingCustomTypeTV": [
    "string*"
  ],
  "ratingCustomTypeMpaa": "string",
  "ratingCustomTypeCaEnglish": "string",
  "ratingCustomTypeCaFrench": "string",
  "unratedLock": "bool"
}

Method: getPlayingContentInfo

versions: [1.0] params

{} // empty input

response

{
  "uri": "string",
  "source": "string",
  "title": "string",
  "dispNum": "string",
  "originalDispNum": "string",
  "tripletStr": "string",
  "programNum": "int",
  "programTitle": "string",
  "startDateTime": "string",
  "durationSec": "int",
  "playSpeed": "string",
  "bivl_serviceId": "string",
  "bivl_assetId": "string",
  "bivl_provider": "string",
  "mediaType": "string"
}

purpose

Gives information about what's currently playing on the TV. A "Now playing"
of sorts. Limited by what the TV itself knows -- if it's on the OSD it's
returned, if not, nothing doing. Not super useful if the TV isn't the
source of your media.

Method: getPlayingContentInfo

versions: [1.0] params

{} // empty input

response

{
  "uri": "string",
  "source": "string",
  "title": "string",
  "dispNum": "string",
  "originalDispNum": "string",
  "tripletStr": "string",
  "programNum": "int",
  "programTitle": "string",
  "startDateTime": "string",
  "durationSec": "int",
  "playSpeed": "string",
  "bivl_serviceId": "string",
  "bivl_assetId": "string",
  "bivl_provider": "string",
  "mediaType": "string"
}

purpose

I mean it's the same as version 1? Literally no difference? Maybe if you
had dual tuners or something?

Method: getSchemeList

versions: [1.0] params

{} // empty input

response

{
  "scheme": "string",
}


[
  "getSchemeList",
  [],
  [
    "{\"scheme\":\"string\"}*"
  ],
  "1.0"
],
[
  "getSourceList",
  [
    "{\"scheme\":\"string\"}"
  ],
  [
    "{\"source\":\"string\"}*"
  ],
  "1.0"
],
[
  "getSourceList2",
  [
    "{\"scheme\":\"string\"}"
  ],
  [
    "{\"source\":\"string\"}*"
  ],
  "1.0"
],
[
  "getVersions",
  [],
  [
    "string*"
  ],
  "1.0"
],
[
  "setDeleteProtection",
  [
    "{\"uri\":\"string\",\"isProtected\":\"bool\"}"
  ],
  [],
  "1.0"
],
[
  "setFavoriteContentList",
  [
    "{\"favSource\":\"string\",\"contents\":\"string-array\"}"
  ],
  [],
  "1.0"
],
[
  "setPlayContent",
  [
    "{\"uri\":\"string\"}"
  ],
  [],
  "1.0"
],
[
  "setPlayTvContent",
  [
    "{\"channel\":\"string\"}"
  ],
  [],
  "1.0"
],
[
  "setTvContentVisibility",
  [
    "{\"uri\":\"string\",\"epgVisibility\":\"string\",\"channelSurfingVisibility\":\"string\",\"visibility\":\"string\"}*"
  ],
  [],
  "1.0"
],
[
  "getContentCount",
  [
    "{\"source\":\"string\",\"type\":\"string\",\"target\":\"string\"}"
  ],
  [
    "{\"count\":\"int\"}"
  ],
  "1.1"
],
[
  "getMethodTypes",
  [
    "string"
  ],
  [
    "string",
    "string*",
    "string*",
    "string"
  ],
  "1.1"
],
[
  "getVersions",
  [],
  [
    "string*"
  ],
  "1.1"
],
[
  "getContentList",
  [
    "{\"source\":\"string\",\"stIdx\":\"int\",\"cnt\":\"int\",\"type\":\"string\",\"target\":\"string\"}"
  ],
  [
    "{\"uri\":\"string\",\"title\":\"string\",\"index\":\"int\",\"dispNum\":\"string\",\"originalDispNum\":\"string\",\"tripletStr\":\"string\",\"programNum\":\"int\",\"programMediaType\":\"string\",\"startDateTime\":\"string\",\"durationSec\":\"int\",\"channelName\":\"string\",\"isProtected\":\"bool\",\"directRemoteNum\":\"int\",\"isAlreadyPlayed\":\"bool\"}*"
  ],
  "1.2"
],

Browser /sony/browser

Cec /sony/cec

Encryption /sony/encryption

Guide /sony/guide

Notification /sony/notification

Recording /sony/recording

System /sony/system

Video Screen /sony/videoScreen

curl -H "Content-Type: application/json" \
  -H "X-Auth-PSK: rabbits" \
  -X POST \
  -d '{"id": 20, "method": "getSystemSupportedFunction", "version": "1.0", "params": [""]}' \
  http://192.168.0.98/sony/system
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment