Sony BD Player Plugin

This is a plugin for a Sony Blu-ray Player that is controlled over IP.

I have a Sony BDP-S3700 and I am not familiar enough with how various kinds of Sony BD players are controlled, so this may only work with a subset, at least without a little modification. I pulled parts of it from these topics on controlling other Sony devices:

I also included the Wake-on-LAN functionality discussed in one of the topics from the old forum and I added a Select command that wasn’t present in the linked documentation that I got from iRule.

The plugin has 5 settings that can be configured: Host, Port, MAC, UseIPforWOL, and WOLPort. Host should be set to the player’s hostname/IP address and port seems to vary based on the specific model of BD player (50001, 52323, or even 80). MAC is the MAC address of the player. UseIPforWOL, if it is set to anything other than an empty string, will also send the Host and, if specified, WOLPort in the WOL message. My particular player only needs the MAC address, but the WOL API supports the additional information so I included but did not test them.

Last Updated: 2020-04-28
SonyBDPlayer-2020-04-28.plugin (7.2 KB)

plugin.Name = "SonyBDPlayer";
plugin.OnChangeRequest = onChangeRequest;
plugin.OnConnect = onConnect;
plugin.OnDisconnect = onDisconnect;
plugin.OnPoll = onPoll;
plugin.OnSynchronizeDevices = onSynchronizeDevices;
plugin.PollingInterval = -1;
plugin.DefaultSettings = {
    "Host"          : "192.168.1.1",
    "Port"          : "50001",  // some use 52323 or standard 80 instead
    "MAC"           : "11:22:33:44:55:66",
    "UseIPforWOL"   : "",   // set this to anything other than empty string if need to send IP (and port) for WOL; host must be IP address and not name in this case
    "WOLPort"       : "",   // standard is 9; if left empty, the port will not be sent
};

var VERSION = "2020-04-28";

var http = new HTTPClient();

var powerOn = false;

var mediaCommandMappings = {
    "PowerOn"       : "WOL",
    "PowerOff"      : "AAAAAwAAHFoAAAAVAw==",

    "DirectionUp"   : "AAAAAwAAHFoAAAA5Aw==",
    "DirectionLeft" : "AAAAAwAAHFoAAAA7Aw==",
    "DirectionDown" : "AAAAAwAAHFoAAAA6Aw==",
    "DirectionRight": "AAAAAwAAHFoAAAA8Aw==",
    "Select"        : "AAAAAwAAHFoAAAA9Aw==",

    "Home"          : "AAAAAwAAHFoAAABCAw==",
    "Options"       : "AAAAAwAAHFoAAAA/Aw==",
    "Return"        : "AAAAAwAAHFoAAABDAw==",

    "Number1"       : "AAAAAwAAHFoAAAAAAw==",
    "Number2"       : "AAAAAwAAHFoAAAABAw==",
    "Number3"       : "AAAAAwAAHFoAAAACAw==",
    "Number4"       : "AAAAAwAAHFoAAAADAw==",
    "Number5"       : "AAAAAwAAHFoAAAAEAw==",
    "Number6"       : "AAAAAwAAHFoAAAAFAw==",
    "Number7"       : "AAAAAwAAHFoAAAAGAw==",
    "Number8"       : "AAAAAwAAHFoAAAAHAw==",
    "Number9"       : "AAAAAwAAHFoAAAAIAw==",
    "Number0"       : "AAAAAwAAHFoAAAAJAw==",

    "Display"       : "AAAAAwAAHFoAAABBAw==",
    "Audio"         : "AAAAAwAAHFoAAABkAw==",
    "SubTitle"      : "AAAAAwAAHFoAAABjAw==",
    "Favorites"     : "AAAAAwAAHFoAAABeAw==",

    "Yellow"        : "AAAAAwAAHFoAAABpAw==",
    "Blue"          : "AAAAAwAAHFoAAABmAw==",
    "Red"           : "AAAAAwAAHFoAAABnAw==",
    "Green"         : "AAAAAwAAHFoAAABoAw==",

    "Play"          : "AAAAAwAAHFoAAAAaAw==",
    "Stop"          : "AAAAAwAAHFoAAAAYAw==",
    "Pause"         : "AAAAAwAAHFoAAAAZAw==",
    "Rewind"        : "AAAAAwAAHFoAAAAbAw==",
    "FastForward"   : "AAAAAwAAHFoAAAAcAw==",
    "Prev"          : "AAAAAwAAHFoAAABXAw==",
    "Next"          : "AAAAAwAAHFoAAABWAw==",
    "SkipBackward"  : "AAAAAwAAHFoAAAB2Aw==",
    "SkipForward"   : "AAAAAwAAHFoAAAB1Aw==",

    "Angle"         : "AAAAAwAAHFoAAABlAw==",
    "TopMenu"       : "AAAAAwAAHFoAAAAsAw==",
    "PopUpMenu"     : "AAAAAwAAHFoAAAApAw==",
    "Eject"         : "AAAAAwAAHFoAAAAWAw==",

    "Karaoke"       : "AAAAAwAAHFoAAABKAw==",
    "Qriocity"      : "AAAAAwAAHFoAAABMAw==",
    "Netflix"       : "AAAAAwAAHFoAAABLAw==",
    "Mode3D"        : "AAAAAwAAHFoAAABNAw==",
};



function onChangeRequest(device, attribute, value) {
    console.log("onChangeRequest called...");

    var host = plugin.Settings["Host"];
    var port = plugin.Settings["Port"];
    var mac = plugin.Settings["MAC"];
    var useipforwol = (plugin.Settings["UseIPforWOL"] == "") ? false : true;
    var wolport = plugin.Settings["WOLPort"];

    switch(attribute) {
        case "MediaCommand":

            var cmd = mediaCommandMappings[value];

            if(cmd) {
                if(cmd == "WOL") {
                    console.log("  MAC: " + mac);
                    console.log("  use IP for WOL?: " + useipforwol);
                    console.log("  Host: " + host);
                    console.log("  WOLPort: " + wolport);

                    var wolOpts = {};
                    if(useipforwol) {
                        wolOpts["address"] = host;
                        if(wolport != "") {
                            wolOpts["port"] = parseInt(wolport);
                        }

                        console.log("  sending WOL to: " + mac + " with " + wolOpts);
                        WOL.wake(mac, wolOpts);

                    } else {
                        console.log("  sending WOL to: " + mac);
                        WOL.wake(mac);
                    }

                    // very simple power state monitoring
                    powerOn = true;

                } else if(!powerOn && value == "PowerOff") {
                    // we're not on, so don't try to turn us off (this avoid an annoying message in some situations)
                    console.log("  not powered on, so power off command ignored");

                } else {
                    var url = "";
                    var body = "";
                    var httpOptions = {};

                    console.log("  Host: " + host);
                    console.log("  Port: " + port);

                    url += "http://" + host;
                    if(port != 80) {
                        url += ":" + port;
                    }
                    // NOTE: some devices apparently use "/sony/IRCC" instead
                    url +=  "/upnp/control/IRCC";

                    body += "<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>";
                    body += cmd;
                    body += "</IRCCCode></u:X_SendIRCC></s:Body></s:Envelope>";

                    httpOptions = {
                        headers: {
                            "Content-Type" : "text/xml",
                            "SOAPACTION" : "\"urn:schemas-sony-com:service:IRCC:1#X_SendIRCC\"",
                        }
                    };

                    console.log("  sending request to: " + url);
                    console.log("  command: " + cmd);

                    http.post(url, body, httpOptions);

                    if(value == "PowerOff") {
                        // update power state
                        powerOn = false;
                    }

                    // all done
                }

            } else {
                console.log("ERROR: unsupported command: " + value);
            }

            break;

        default:
            console.log("ERROR: unsupported attribute type: " + attribute);
            break;
    }
}

function onConnect() {
    console.log("onConnect called...");

    var device = plugin.Devices[plugin.Name];

    if(device) {
        console.log("  setting supported media commands...");
        device.SupportedMediaCommands = Object.keys(mediaCommandMappings);
        console.log("  set...");
    }
}

function onDisconnect() {
    console.log("onDisconnect called...");
}

function onPoll() {
    console.log("onPoll called...");
}

function onSynchronizeDevices() {
    console.log("onSynchronizeDevices called...");

    var device = new Device();

    device.Name = plugin.Name;  // override default naming conversion so it looks nicer
    device.Id = plugin.Name;
    device.DisplayName = "Sony BD Player";
    device.Icon = "Disc";
    device.Capabilities = [ "MediaControl" ];
    device.Attributes = [ ];

    plugin.Devices[plugin.Name] = device;

    console.log("  done syncing");
}
1 Like