node-red-contrib-dellmonitor
Version:
RS232 over network control of a Dell CS5517H LCD Monitor
201 lines (185 loc) • 6.62 kB
JavaScript
var sendHeader = [0x37, 0x51];
var receiveHeader = [0x6F, 0x37];
var getBit = 0xEB;
var setBit = 0xEA;
var commandSet = {
"name": 0x01,
"serialNumber": 0x02,
"powerState": 0x20,
"powerLED": 0x21,
"powerUSB": 0x22,
"resetPower": 0x2F,
"brightness": 0x30,
"contrast": 0x31,
"sharpness": 0x34,
"videoInputAutoSelect": 0x60,
"videoInput": 0x62
};
var stateBits = {
"off": [0x00],
"on": [0x01]
};
var inputBits = {
"HDMI1": [0x01, 0x00, 0x00, 0x00],
"HDMI2": [0x02, 0x00, 0x00, 0x00],
"DP1": [0x08, 0x00, 0x00, 0x00],
"VGA1": [0x40, 0x00, 0x00, 0x00],
}
module.exports = {
state: stateBits,
inputs: inputBits,
command: commandSet,
//Send a request for status when something else changes the state
generateRequestOnChange: function(message) {
return generateRawCommand(0xEB, message[5]);
},
generateBuffer: function(direction, command, data) {
switch(direction) {
case "set": direction = setBit; break;
case "get": direction = getBit; break;
default: return "Incorrect Direction";
}
//Get command
for(var key in commandSet) {
if(key.toString().toLowerCase() == command.toString().toLowerCase()) {
command = commandSet[key];
}
}
//Set data
if(data !== undefined && data !== null) {
switch(command) {
case commandSet.name: data = new Buffer(data); break;
case commandSet.serialNumber: data = new Buffer(data); break;
case commandSet.powerState:
case commandSet.videoInputAutoSelect:
case commandSet.powerLED:
case commandSet.powerUSB:
case commandSet.resetPower: data = [data == "on"]; break;
case commandSet.brightness: data = [data];
case commandSet.contrast: data = [data];
case commandSet.sharpness: data = [data];
case commandSet.videoInput: {
for(var key in inputBits) {
if(key.toString().toLowerCase() == data.toString().toLowerCase()) {
data = inputBits[key];
}
}
break;
}
}
}
var rawCommand = generateRawCommand(direction, command, data);
return rawCommand;
},
generateRaw: generateRawCommand,
isReceivedValid: function(message) {
if(message[0] != receiveHeader[0]){return false;}
if(message[1] != receiveHeader[1]){return false;}
if(message[2] != (2 + getDataRaw(message).length)){return false;}
if(message[3] != 0x02){return false;}
var CRC = receiveHeader[0] ^ receiveHeader[1] ^ (2 + getDataRaw(message).length) ^ 0x02 ^ message[4];
for(var i = 0; i < getDataRaw(message).length; i++) {
CRC ^= getDataRaw(message)[i];
}
if(message[message.length - 1] != CRC){return false;}
return true;
},
getResultCode: function(message) {
switch(message[4]) {
case 0x00: return "success";
case 0x01: return "timeout";
case 0x02: return "parametersError";
case 0x03: return "notConnected";
case 0x04: return "otherError";
}
},
getCommand: getCommand,
getData: function(message) {
switch(message[5]) {
case commandSet.name: {
return message.slice(6, message.length -1).toString();
break;
}
case commandSet.serialNumber: {
return message.slice(6, message.length -1).toString();
break;
}
case commandSet.powerState: {
if(message[6] == stateBits.off){return "off";}
else if(message[6] == stateBits.on){return "on";}
break;
}
case commandSet.powerLED: {
if(message[6] == stateBits.off){return "off";}
else if(message[6] == stateBits.on){return "on";}
break;
}
case commandSet.resetPower: {
return undefined;
break;
}
case commandSet.brightness: {
return message[6];
break;
}
case commandSet.contrast: {
return message[6];
break;
}
case commandSet.sharpness: {
return message[6];
break;
}
case commandSet.videoInputAutoSelect: {
if(message[6] == stateBits.off){return "off";}
else if(message[6] == stateBits.on){return "on";}
break;
}
case commandSet.videoInput: {
for(var key in inputBits) {
if(inputBits[key][0] == message[6]){return key.toString();}
}
break;
}
}
}
}
//Get the friendly command
function getCommand(message) {
//Get command
for(var key in commandSet) {
if(commandSet[key] == message[5]){return key;}
}
}
//Get the raw data stream
function getDataRaw(message) {
return message.slice(5, message.length -1);
}
//Generate the raw command
function generateRawCommand(readWriteBit, command, data) {
//H1 H2 Length R/W Command Data CHK (Xor byte by byte)
var buffer = new Buffer(5);
var dataLength;
if(data === undefined || data == null){dataLength = 0;}else{dataLength = data.length;}
var CRC = sendHeader[0] ^ sendHeader[1] ^ (2 + dataLength) ^ readWriteBit ^ command;
if(dataLength > 0) {
for(var i = 0; i < data.length; i++) {
CRC ^= data[i];
}
}
buffer.writeUInt8(sendHeader[0], 0);
buffer.writeUInt8(sendHeader[1], 1);
buffer.writeInt8(2 + dataLength, 2);
buffer.writeUInt8(readWriteBit, 3);
buffer.writeUInt8(command, 4);
if(dataLength > 0) {data = Buffer.from(data);}
var CRCBuffer = new Buffer(1);
CRCBuffer.writeUInt8(CRC);
if(dataLength > 0){
var finalBuffer = Buffer.concat([buffer, data, CRCBuffer]);
}
else {
var finalBuffer = Buffer.concat([buffer, CRCBuffer]);
}
return finalBuffer;
}