Closed muldy closed 7 years ago
This was the same issue I had when writing this module and there just seems to be a lack of documentation from Sony about this.
However, the TV's actually have an API that returns all the available methods, versions, parameters and return values. You can invoke this information yourself, by calling for example bravia.audio.getMethodTypes()
which will return a JSON response containing all the audio methods available for all the different versions of the API. You can also pass in a version string to the method if you just want to query the methods available for a particular API.
I found that most of the parameters and return values are fairly self explanatory but unfortunately there are some that I don't really have a clue what they mean.
There are a bunch of other "service protocols" available, that can be accessed as bravia.system.getMethodTypes()
etc. The ones that are available are:
accessControl appControl audio avContent browser cec encryption guide recording system videoScreen
I should update the README to include this information as to be fair it isn't obvious if you've not got much experience with the Bravia API.
I hope this helps.
Wayne
Thanks,
Yes, I've been listing the protocols and the geMethodTypes like system:
[{"version":"1.0","methods":[["getCurrentTime",[],["string"],"1.0"],["getDeviceMode",["{\"value\":\"string\"}"],["{\"isOn\":\"bool\"}"],"1.0"],["getInterfaceInformation",[],["{\"productCategory\":\"string\", \"productName\":\"string\", \"modelName\":\"string\", \"serverName\":\"string\", \"interfaceVersion\":\"string\"}"],"1.0"],["getLEDIndicatorStatus",[],["{\"mode\":\"string\", \"status\":\"string\"}"],"1.0"],["getNetworkSettings",["{\"netif\":\"string\"}"],["{\"netif\":\"string\", \"hwAddr\":\"string\", \"ipAddrV4\":\"string\", \"ipAddrV6\":\"string\", \"netmask\":\"string\", \"gateway\":\"string\", \"dns\":\"string*\"}*"],"1.0"],["getPowerSavingMode",[],["{\"mode\":\"string\"}"],"1.0"],["getPowerStatus",[],["{\"status\":\"string\"}"],"1.0"],["getRemoteControllerInfo",[],["{\"bundled\":\"bool\", \"type\":\"string\"}","{\"name\":\"string\", \"value\":\"string\"}*"],"1.0"],["getRemoteDeviceSettings",["{\"target\":\"string\"}"],["{\"target\":\"string\", \"currentValue\":\"string\", \"deviceUIInfo\":\"string\", \"title\":\"string\", \"titleTextID\":\"string\", \"type\":\"string\", \"isAvailable\":\"Boolean\", \"candidate\":\"GeneralSettingsCandidate[]\"}*"],"1.0"],["getSystemInformation",[],["{\"product\":\"string\", \"region\":\"string\", \"language\":\"string\", \"model\":\"string\", \"serial\":\"string\", \"macAddr\":\"string\", \"name\":\"string\", \"generation\":\"string\", \"area\":\"string\", \"cid\":\"string\"}"],"1.0"],["getSystemSupportedFunction",[],["{\"option\":\"string\", \"value\":\"string\"}*"],"1.0"],["getWolMode",[],["{\"enabled\":\"bool\"}"],"1.0"],["requestReboot",[],[],"1.0"],["setDeviceMode",["{\"value\":\"string\", \"isOn\":\"bool\"}"],[],"1.0"],["setLanguage",["{\"language\":\"string\"}"],[],"1.0"],["setPowerSavingMode",["{\"mode\":\"string\"}"],[],"1.0"],["setPowerStatus",["{\"status\":\"bool\"}"],[],"1.0"],["setWolMode",["{\"enabled\":\"bool\"}"],[],"1.0"],["getMethodTypes",["string"],["string","string*","string*","string"],"1.0"],["getVersions",[],["string*"],"1.0"]]},{"version":"1.1","methods":[["getCurrentTime",[],["{\"dateTime\":\"string\", \"timeZoneOffsetMinute\":\"int\", \"dstOffsetMinute\":\"int\"}"],"1.1"],["setLEDIndicatorStatus",["{\"mode\":\"string\", \"status\":\"string\"}"],[],"1.1"]]}]
Ok, so for the actual method parameters is just a best guess :)
Yeah sadly, if you manage to find some documentation then please come back and let me know :)
You're both on the right tracks - the documentation is there in the getMethodTypes queries. If you look at the setAudioVolume method definition in the audio.getMethodTypes() response:
["setAudioVolume", [{
"target": "string",
"volume": "string"
}], ["int"], "1.0"]
The volume needs to be given as a string and not as an integer. Int is what the setAudioVolume query would return (it returns a 0
for me, even when the query succeeds instead of anything meaningful...). Here's a pull request to fix the demo in readme: #4
How does the getSpeakerSettings method work then? Checking the getMethodTypes, a target string is needed:
["getSpeakerSettings", [{
"target": "string"
}], [{
"target": "string",
"currentValue": "string",
"deviceUIInfo": "string",
...
}*], "1.0"]
First I tried speaker and headphone as the target but those return an "Illegal Argument" error. By trial and error I figured out that querying it with an empty object {}
as the params gets us the possible targets:
bravia.audio.invoke("getSpeakerSettings", "1.0", {}).then(function(info) {
console.log("speaker settings", info);
}).catch(function(err) {
console.error("speaker settings err", err);
});
[{
"target": "tvPosition",
"currentValue": "tableTop"
}, {
"target": "subwooferLevel",
"currentValue": "17"
}, {
"target": "subwooferFreq",
"currentValue": "8"
}, {
"target": "subwooferPhase",
"currentValue": "normal"
}, {
"target": "subwooferPower",
"currentValue": "on"
}]
I wish there was an actual documentation for this stuff but I guess Github comments will have to do 😄
Awesome, thank you for experimenting and fixing the documentation. Maybe, we can start a wiki on this and try and complete as much documentation on the API as we can, thoughts?
P.S. I don't have access to a Bravia TV as originally wrote this library for a friend, can get the odd access but won't make this very easy for me to do on my own but with you guys contributions I think it's certainly possible!
Just wanted to let you know, the help file on NPM still says volume: 50 instead of '50'.
One question: When I try to getMethodTypes(), I end up with this instead of actual types.
[ { version: '1.0', methods: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ] }, { version: '1.1', methods: [ [Object], [Object] ] } ]
I'm still fairly new to node js, any direction you can give me to get the actual list would be great. Everything else is working great. Thanks for your work.
I'm just testing another update to the code so once this is done I'll push the latest changes to NPM.
You'll need to use util.inspect()
. See util.inspect()
I don't know if having a sony subwoofer and soundbar hooked up changes anything but this is what I've figured out. Everything works for me except changing the volume. I have everything else voice controlled by an amazon echo. I can change volume level to 'speaker' and when I get the value, it is where I set it. The TV does not actually change volume on hdmi1 but I did notice that it IS changing the volume on the home screen.
I was hoping that the setSpeakerSettings would be corresponding to the operation pressing: Action Menu -> Speakers -> Tv Speakers/Audio System. I would like to automate this...
Confirmed. After turning off the sound bar, changing the sound works perfectly. I just need to figure out how to change the connected audio which we normally control with the normal tv remote.
What does the following return as @ilessiivi wrote above:
bravia.audio.invoke("getSpeakerSettings", "1.0", {}).then(function(info) {
console.log("speaker settings", info);
}).catch(function(err) {
console.error("speaker settings err", err);
});
This:
speaker settings [ { target: 'tvPosition', currentValue: 'wallMount' }, { target: 'subwooferLevel', currentValue: '17' }, { target: 'subwooferFreq', currentValue: '8' }, { target: 'subwooferPhase', currentValue: 'normal' }, { target: 'subwooferPower', currentValue: 'on' } ]
You've probably already tried it but just interested to know that if you invoke the setAudioVolume
method using one of the targets you got back i.e. 'subwooferLevel' if that changes the volume level for it or not?
I think somewhere in the TV settings there is a option to connect a subwoofer to the headphones jack ... So the subwoofer levels must be for that option? I think I've tried reading these values, when I change from Tv speakers to Audio system and see no change in them...
Maybe some target parameter gets the Audio System levels...
The whole issue for me is HDMI-CEC. Is it possible to send a command that talks to the Sony HDMI/ARC? I get almost identical results from getspeakersettings as muldy. The soundbar volume can be controlled by it's own remote or by the bravia remote which makes me wonder if there is a way to send the volume command to CEC. I've tried changing subwoofer and also the headphone settings which don't have any results.
Hi, It was myself and Wayne that started investigating this some months ago, we are currently testing again, unfortunately I am unable to fully test the audio setup you guys have as I am currently using a sound bar connected via Optical so no ARC.
I think the best way to try and move this on will be to install the TV & Video sidesview app (official Sony app) on an IOS or Android device and try changing the volume and see if that adjusts it, if it does we can look into packet capturing.
Also worth checking the home theatre control settings, I have no idea what options there are as It obviously doesn't detect arc but this may have some useful settings
I'm using a Yamaha 5.1(Without ARC) system through optical cable too. For normal Tv usage I don't turn on the Yamaha amplifier, but when I see movies, I turn the Amp on, switch to HDM1... and I have to set the speakers settings to Audio system... and when I'm done I have to put it back to the TV speakers (YAWWN). This is because With Kodi on android I can't get DTS audio out of the Optical, so I use a raspberry pi...
@muldy Me and James are playing around with his TV as we speak to see if we can help crack it for you. Interestingly enough calling the API method: audio.getSoundSettings
method which is on version 1.1 seems to give back whether it's on speaker or audioSystem, although, for us seems to be back to front. Can you try on yours and see what you get back.
@muldy It seems that changing the speaker mode between TV and Audio System is most likely possible using the audio.setSoundSettings
method, however, sadly we cannot work out what is meant by GeneralSettings[]
, can only assume the parameter would look something like:
{ "settings": [
{ ... } // <-- Unknown what goes in this "GeneralSettings" object.
] }
We've tried a bunch of these but everything gives back an illegal argument error and surprise, surprise not once ounce of documentation anywhere available on it...
@AmigaZoid What happens if you invoke:
bravia.audio.invoke("getVolumeInformation", "1.0", {}).then(function(info) {
console.log(info);
}).catch(function(err) {
console.error(err);
});
I'm interested to know whether you have more than just speaker and headphone as targets.
I have emailed Sony support to see if they will give us API documentation, will update when I have one.
Please let me know if you figure it out. I'm in the process of a OS reinstall so will try the command above once I have Node reinstalled.
@AmigaZoid I most certainly will do that will be really useful for me. When you have completed your project, would this be something you would be willing to share as I know my friend (who I originally wrote this module for) is looking to do exactly the same as you and he isn't a programmer and I don't have much time to help him. Also, when you have reinstalled your OS and have some time let us know what results you get back from the getVolumeInformation
method as this may hold the answer.
I have now created a new issue for what all of us here are really after. You can find it here.
[ { target: 'speaker', volume: 2, mute: false, maxVolume: 100, minVolume: 0 }, { target: 'headphone', volume: 26, mute: false, maxVolume: 100, minVolume: 0 } ]
Same info I had before for getspeakersettings
As for the alexa setup, sure I can share. It's really minimal code for the way I am achieving it. I have a normal Alexa app and lambda that is going through AWS.Iot. So I have a subscribe/publish setup through iot that simply post a word like TVPower or VolumeUP to the Node server. I simply use an if or a switch to send the bravia code through your script to the TV. I'm doing the same thing for Kodi except I'm sending a JSON with http to the kodi webserver. Planning on adding zwave lights also if I can get it running.
Project 2 is lightening for us but Wayne will also use them so easier to test. Would be interested to know if u are running Kodi natively on theTv (I currently am) of using an external device.
Yes, running kodi on the TV without an external box.
Good to know, Sony's response was basically that they don't provide technical spec to end users which was what we expected, doesn't hurt to ask just great you stumbled on that documentation which should help a lot, just about to look now.
Found an app that the volume control changes the TV and soundbar just like the sony remote. I'll do some sniffing.
Ok so I finally found time to check out the app and used a packet sniffer to examine the commands. It's the standard volumeUp and volumeDown IRCC codes. I testing them by sending the commands and they work.
If you know of an app that allows setting volume at 50% etc., please pass it along. For now I'll just build some loops to raise volume by 10 etc.
Just to confirm using the volume in the ircc changes volume on external devices via arc but the one in the other method simply changes the volume on the TVs but not external arc controlled devices, that seems pretty strange.
using Bravia.send('VolumeUp') or volume down works perfectly but when using an amazon echo, I wanted a quicker way to raise the volume so I tried ... bravia.audio.invoke('setAudioVolume', '1.0', { target: 'speaker', volume: '50' }); This command has no effect on the volume for the TV on HDMI 1 with Dish Network or the sony connected soundbar. It does however affect the volume on the android app home screen.
To get around this with the amazon echo, I simply created a loop so I can ask alexa to raise the volume by 23 etc. If I don't supply a value, it raises or lowers the volume by 5.
ok, If I'm understanding correctly ideally you just want to set the speaker volume to 50 so it is set regardless of what it currently is but simply specifying that doesn't have any impact I wonder if a function to be created that gets the volume status and then involves the vol up or vol down and sends the value accordingly, would have to get Wayne's opinion to see how doable that is.
@AmigaZoid, I have finally had some time to sit down and look through the documentation and found the below, have you tried leaving the target blank, I just tried it and for me it does the same thing as setting the speaker as target (my external audio device has no CEC intelligence) If you haven't already could you try {"target":"", "volume":"50"}
Snippet from the documentation target string 1 Â Output target of sound. Following values are defined. "" - output sound to all output equipment that device has. if mute information of all output is common, this value is set. "speaker" - output sound to speaker "headphone" - output sound to headphone
The volume bar on the TV shows for a couple of seconds but there is no change to the volume. Stays at the same number.
'getDeviceMode',
[ '{"value":"string"}' ],
[ '{"isOn":"bool"}' ],
'1.0' ],
try {
this.deviceMode = await this.client.system.invoke('getDeviceMode', '1.0', {})
}
catch (e) {
debug(this.device, e)
}
try {
this.deviceMode = await this.client.system.invoke('getDeviceMode', '1.0', {value: '*'})
debug(this.deviceMode)
}
catch (e) {
debug(this.device, e)
}
BraviaHost sony-810c Error: Illegal Argument
at bravia._request.then.response (/Users/mschwartz/hosts/bigmoney/github/mschwartz/ha2/node_modules/bravia/src/service-protocol.js:61:18)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:169:7) +2s
BraviaHost sony-810c Error: Illegal JSON
BraviaHost sony-810c Error: Illegal Argument
at bravia._request.then.response (/Users/mschwartz/hosts/bigmoney/github/mschwartz/ha2/node_modules/bravia/src/service-protocol.js:61:18)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:169:7) +31ms
It wants "value":"string" as argument. Any idea what it really wants? :)
The document gives the information below, could you explain what you are using this for, it isn't a method I have previously attempted to use so just curious.
The following does give the status back on mine {"value":"shop"} it can be changed with the set using {"value":"shop", "isOn":bool} not sure if there is any other available modes.
params' Elements An object composed by following pair(s). name type multiplicity default description value string 1 Â Device mode value which you want to know the status. "shop" - mode suitable for shop. JSON Example { "id": 25, "method": "getDeviceMode", "params": [{"value": "shop"}], "version": "1.0" }
I see.
I was investigating a way to find out what is on the TV. Is it playing a Netflix stream? YouTube? Or TV. Is it set to HDMI 1?
And so on.
shop mode must be for display at the store, disable or enable various functionality. That's my guess.
I wanted to note that {} as argument doesn't list the modes for me.
What document? I must be blind or something :)
{} just throws an illegal argument for me too, it isn't you it's the api, someone kindly linked to the official Sony document which is not publicly available but I kept a copy. Legally we can't publish it some of it still doesn't fully explain and requires updating based on findings, there is an open issue at https://github.com/waynehaffenden/bravia/issues/6 For the api documentation but no ones offered and we are struggling to find the time.
I will have a look and see if I can find any method to achieve what you are trying later I can only think of one that lists running app and current input so may require querying both to get the end result will see what I can do when I get a chance.
I think shop mode kind of optimises display and sound for a shop type envireoment rather than the home, that's an assumption on my part not definitive.
I've been exploring the APIs with getMethods() on each of the protocols enumerated in the Bravia instance. Some of them look quite promising.
There's one that returns a list of all the apps with icon/url for images and everything. A method to start one of those, it seems, too. But querying for the active app doesn't show anything when I start netflix from the remote control.
Also, I am polling the TV for volume and power state every 500ms. It's silly they don't have a web socket for that kind of thing (like LG WbOS 3 does). I tried polling faster (so the UI is more responsive), but was getting some http failures (ECONNTIMEOUT) fetching the volume info.
yeah no web sockets that I am aware of, just had a look and there is one about playing content but not sure if it will be usefull seems to be largely related to pulling data from the TVs internal tuners.
Really? I haven't found any way to detect if the TV is showing HDMI1, or playing Netflix or whatever.
It'd be awesome to be able to tell if Netflix is playing, paused, the title of the show, etc., too.
Here's the latest. I was able to configure some favorites (in my code/app, not the TV) for various apps. See them on the right:
The API gives me the icons and uri to launch each, and all that works.
Do you have a method for avContent:1.0:getPlayingContentInfo, I haven't done much in the way of testing but for example I currently have my external Satellite tuner on HDMI 4 and it outputs the following
object uri: "extInput:hdmi?port=4" source: "extInput:hdmi" title: "HDMI 4/ARC"
I have attached the taken screen shots from the documentation, I will be removing shortly but put it there for your reference. Please let me know how you get on, I am not sure this can interact with the apps themselves but would be awesome.
I get an exception, "bad state" when the TV is playing Netflix.
Does it work for you?
I'd love to get my hands on this doc :)
I have sent it over, as I mentioned in the email I can't remove you email from your post so please do so at your earliest convenience.
I haven't tested the Netflix bit yet, just off to play some football, will try and do tonight if I get a chance other wise will be later on in the week.
Thank you so much!
Though I haven't received the email yet.
Shared via Google drive
Hi! I'm working on a Kodi plugin to do various things with my Bravia TV and have been having trouble finding proper documentation as well. Would it be possible for someone to share that doc with me as well? It'd be much appreciated :)
Hi! (this is not a issue) I'm doing a express webapp to use the bravia module provided by you, I'm wondering how you know the syntax for the method calls:
bravia.audio.invoke('setAudioVolume', '1.0', { target: 'speaker', volume: 50 });
Particularly the { target: 'speaker', volume: 50 } part. Is there any source for this information? I'm particularly interested in the syntax for the audio getSpeakerSettings method.I'm planning to publish my app on github when I clean up the code.
Thanks in advance.