Runco Projector Plugin

This is a plugin for a Runco Projector that is controlled over a serial connection by a Global Cache IP2SL.

Here’s a link to the manual (Runco doesn’t make them anymore so I couldn’t find a link on their website):

The plugin has 2 settings that can be configured: Host and Port. Host should be set to the global cache’s IP address and port will almost certainly be 4999, which is the default.

Last updated: 2020-04-28

Here is the plugin code:
RuncoProjector-2020-04-28.plugin (3.4 KB)

plugin.Name = "RuncoProjector";
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"  : "4999",
};

var VERSION = "2020-04-28";

var socket = new TCPClient();

var mediaCommandMappings = {
    "PowerOff"      : "ky pow.off",
    "PowerOn"       : "ky pow.on",
    "PowerToggle"   : "ky pow.tog",
    "Menu"          : "ky menu",
    "DirectionUp"   : "ky cur.up",
    "DirectionLeft" : "ky cur.left",
    "DirectionDown" : "ky cur.down",
    "DirectionRight": "ky cur.righ",
    "Select"        : "ky enter",

    "BlankOn"       : "ky bla.on",
    "BlankOff"      : "ky bla.off",
    "BlankToggle"   : "ky bla.tog",
    "AspectNext"    : "ky asp.sw",
    "Aspect169"     : "ky asp.16.9",
    "Aspect43"      : "ky asp.4.3",
    "AspectLB"      : "ky asp.lett",
    "AspectNarrow"  : "ky asp.narr",
};

var inputSourceMappings = {
    "Input1"        : "ky src.1",
    "Input2"        : "ky src.2",
    "Input3"        : "ky src.3",
    "Input4"        : "ky src.4",
    "Input5"        : "ky src.5",
};


function onChangeRequest(device, attribute, value) {
    console.log("onChangeRequest called...");
    switch(attribute) {
        case "MediaCommand":
        case "InputSource":

            var cmd = "";

            if(attribute == "MediaCommand") {
                cmd = mediaCommandMappings[value];
            } else if(attribute == "InputSource") {
                cmd = inputSourceMappings[value];
            }

            if(cmd) {
                console.log("  sending command: " + cmd);
                socket.send(cmd + "\r");

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

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

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

    var host = plugin.Settings["Host"];
    var port = plugin.Settings["Port"];

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

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

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

        console.log("  setting supported input sources...");
        device.SupportedInputSources = Object.keys(inputSourceMappings);
        console.log("  set...");
    }
    
    console.log("  connecting...");
    socket.connect(host, port);
    console.log("  connected");
}

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

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

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

    var device = new Device();

    device.Id = plugin.Name;
    device.DisplayName = "Runco Projector";
    device.Icon = "TV";
    device.Capabilities = [ "MediaControl", "MediaInputSource" ];
    device.Attributes = [ ];

    plugin.Devices[plugin.Name] = device;

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