Skip to content

Commit

Permalink
Initial Contribution
Browse files Browse the repository at this point in the history
  • Loading branch information
tmrobert8 committed Jun 23, 2017
1 parent 41685ce commit a959049
Show file tree
Hide file tree
Showing 14 changed files with 845 additions and 0 deletions.
30 changes: 30 additions & 0 deletions device/GlobalCache/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict';

module.exports = Object.freeze({
BEACON_TYPE_CC: "CC",
BEACON_TYPE_IR: "IR",
BEACON_TYPE_SR: "SR",

BEACON_UUID: "UUID",
BEACON_MODEL: "Model",
BEACON_URL: "Config-URL",

LINK_TYPE_3RELAY: "3 RELAY",
LINK_TYPE_3IR: "3 IR",
LINK_TYPE_1SERIAL: "1 SERIAL",
LINK_TYPE_1IR: "1 IR",
LINK_TYPE_1IRBLASTER: "1 IR_BLASTER",
LINK_TYPE_1IRTRIPORT: "1 IRTRIPORT",
LINK_TYPE_1IRTRIPORTBLASTER: "1 IRTRIPORT_BLASTER",

COMMAND_GETDEVICES: "getdevices",
COMMAND_GETSTATE: "getstate",
COMMAND_SETSTATE: "setstate",
COMMAND_SENDIR: "sendir",

RESPONSE_SETSTATE: "setstate",
RESPONSE_STATE: "state",
RESPONSE_IR: "completeir",

PORT_NUMBER: 4998
});
70 changes: 70 additions & 0 deletions device/GlobalCache/contactClosureController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
'use strict';

const BluePromise = require('bluebird');

const discovery = require('./deviceDiscovery');
const constants = require('./constants');
const gcUtils = require('./gcUtils');

module.exports = class ContactClosureController {
constructor(neeoapi) {
this._neeoapi = neeoapi;
}

buildDevice() {
return this._neeoapi.buildDevice('IP2CC')
.setManufacturer('GlobalCache')
.addAdditionalSearchToken('itach')
.addAdditionalSearchToken('simple blaster')
.addSwitch({ name: 'closeContact', label: 'Contact' },
{ setter: this._setSwitch, getter: this._getSwitch }
)
.enableDiscovery({
headerText: 'Contact Closure Settings',
description: 'No additional setup for contact closure'
}, this._discoverDevices)
.setType('ACCESSOIRE');
}

_setSwitch(deviceid, value) {
const valueToSet = value === "true" ? '1' : '0';
return new BluePromise((resolve, reject) => {
const device = gcUtils.parseDeviceId(deviceid)

return discovery.getDevice(device.uuid)
.then(results => {
return results.setState(device.module, device.port, valueToSet)
})
.then(function (rc) {
if (rc !== valueToSet) {
throw new Error("State was not correctly set on the device - expecting " + valueToSet + " but got " + rc);
}
})
.catch(function (e) {
console.error("Error setting switch value. ", e.message);
});
});
}

_getSwitch(deviceid) {
return new BluePromise((resolve, reject) => {
const device = gcUtils.parseDeviceId(deviceid)

return discovery.getDevice(device.uuid)
.then(results => {
return results.getState(device.module, device.port)
})
.then(function (state) {
return state !== '0';
});
});
}

_discoverDevices() {
return discovery
.getDevicePorts(constants.BEACON_TYPE_CC)
.map(function (port) {
return gcUtils.createDeviceDiscovery(port);
});
}
};
15 changes: 15 additions & 0 deletions device/GlobalCache/contactClosureFactory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

const ContactClosureController = require('./contactClosureController');

module.exports = class ContactClosureFactory {
constructor(neeoapi) {
this._device = new ContactClosureController(neeoapi).buildDevice();
}

buildDevices() {
return [
this._device
];
}
};
13 changes: 13 additions & 0 deletions device/GlobalCache/definitions/Lutron QED.ir
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{ "name": "QED Raise", "label": "QED Raise", "cmd": "1,40000,1,15,732,91,457,91,91,183,91,274,91,274,91,274,91,183,732,91,457,91,91,183,91,274,91,274,91,274,91,183" },
{ "name": "QED Lower", "label": "QED Lower", "cmd": "1,40000,1,15,732,91,457,91,91,183,91,274,91,366,91,91,91,274,732,91,457,91,91,183,91,274,91,366,91,91,91,274" },
{ "name": "QED Open and Preset", "label": "QED Open and Preset", "cmd": "1,40000,1,15,732,91,457,91,91,183,91,91,91,366,91,274,91,274,732,91,457,91,91,183,91,91,91,366,91,274,91,274" },
{ "name": "QED Open", "label": "QED Open", "cmd": "1,40000,1,15,732,91,457,91,91,274,274,91,91,274,274,91,91,91,732,91,457,91,91,274,274,91,91,274,274,91,91,91" },
{ "name": "QED Close", "label": "QED Close", "cmd": "1,40000,1,15,732,91,457,91,91,274,274,91,91,274,91,183,91,183,732,91,457,91,91,274,274,91,91,274,91,183,91,183" },
{ "name": "QED Preset1", "label": "QED Preset1", "cmd": "1,40000,1,15,732,91,457,91,91,274,274,91,91,183,91,183,91,274,732,91,457,91,91,274,274,91,91,183,91,183,91,274" },
{ "name": "QED Preset2", "label": "QED Preset2", "cmd": "1,40000,1,17,732,91,457,91,91,274,274,91,91,183,91,91,91,91,183,91,732,91,457,91,91,274,274,91,91,183,91,91,91,91,183,91" },
{ "name": "QED Preset3", "label": "QED Preset3", "cmd": "1,40000,1,15,732,91,457,91,91,274,274,91,91,91,274,274,91,91,732,91,457,91,91,274,274,91,91,91,274,274,91,91" },
{ "name": "QED Open and Close", "label": "QED Open and Close", "cmd": "1,40000,1,15,732,91,457,91,91,183,91,91,91,457,91,91,91,366,732,91,457,91,91,183,91,91,91,457,91,91,91,366" },
{ "name": "QED Open and Raise", "label": "QED Open and Raise", "cmd": "1,40000,1,15,732,91,457,91,91,183,91,91,91,366,274,183,91,183,732,91,457,91,91,183,91,91,91,366,274,183,91,183" },
{ "name": "QED Open and Lower", "label": "QED Open and Lower", "cmd": "1,40000,1,15,732,91,457,91,91,183,91,91,91,366,457,91,91,91,732,91,457,91,91,183,91,91,91,366,457,91,91,91" }
]
204 changes: 204 additions & 0 deletions device/GlobalCache/device.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
'use strict';

const BluePromise = require('bluebird');
const net = require('net');
const rl = require('readline');
const util = require('util');

const constants = require('./constants');
const DevicePort = require('./devicePort');

module.exports = Device;

function Device(beacon) {
this.beacon = beacon;
this.created = Date.now();
}

Device.prototype.getUUID = function () {
return this.beacon[constants.BEACON_UUID];
}

Device.prototype.getModel = function () {
return this.beacon[constants.BEACON_MODEL];
}

Device.prototype.getUrl = function () {
return this.beacon[constants.BEACON_URL];
}

Device.prototype.getIpAddress = function () {
const url = this.beacon[constants.BEACON_URL];
const idx = url.indexOf('://');
if (idx >= 0) {
return url.substring(idx + 3);
} else {
return url;
}
}

Device.prototype.getCreated = function () {
return this.created;
}

Device.prototype.getModulePorts = function () {
const device = this;
return new BluePromise(function (resolve, reject) {
const socket = net.createConnection(constants.PORT_NUMBER, device.getIpAddress());
socket
.on('connect', function () {
const devices = [];
const cmd = util.format('%s', constants.COMMAND_GETDEVICES);

rl.createInterface(socket, socket).on('line', function (line) {
console.log('Received (%s): %s', cmd, line);
if (line === 'endlistdevices') {
resolve(devices);
socket.destroy();
} else {
const args = line.split(',');
if (args.length === 3 && args[0] === 'device') {
if (args[1] !== '0') { // ignore the root module (ethernet/wifi)
switch (args[2]) {
case constants.LINK_TYPE_3RELAY:
devices.push(new DevicePort(device, args[1], 1, constants.BEACON_TYPE_CC));
devices.push(new DevicePort(device, args[1], 2, constants.BEACON_TYPE_CC));
devices.push(new DevicePort(device, args[1], 3, constants.BEACON_TYPE_CC));
break;
case constants.LINK_TYPE_1SERIAL:
devices.push(new DevicePort(device, args[1], args[1], constants.BEACON_TYPE_SR));
break;
case constants.LINK_TYPE_1IR:
case constants.LINK_TYPE_1IRBLASTER:
devices.push(new DevicePort(device, args[1], 1, constants.BEACON_TYPE_IR));
break;
case constants.LINK_TYPE_3IR:
case constants.LINK_TYPE_1IRTRIPORT:
case constants.LINK_TYPE_1IRTRIPORTBLASTER:
devices.push(new DevicePort(device, args[1], 1, constants.BEACON_TYPE_IR));
devices.push(new DevicePort(device, args[1], 2, constants.BEACON_TYPE_IR));
devices.push(new DevicePort(device, args[1], 3, constants.BEACON_TYPE_IR));
break;
default:
console.error('Unknown port type: ' + line);
break;
}
}
} else {
reject('Unknown response: ' + line);
socket.destroy();
}
}
});
console.log('Sending %s', cmd);
socket.write(cmd + '\r');
})
.on('error', function (err) {
socket.destroy();
reject(err);
});
});
};

Device.prototype.setState = function (module, port, state) {
const device = this;
return new BluePromise(function (resolve, reject) {
const socket = net.createConnection(constants.PORT_NUMBER, device.getIpAddress());
socket
.on('connect', function () {
const cmd = util.format('%s,%s:%s,%s', constants.COMMAND_SETSTATE, module, port, state);

rl.createInterface(socket, socket).on('line', function (line) {
console.log('Received (%s): %s', cmd, line);
const args = line.split(',');
if (args.length === 3 && (args[0] === constants.RESPONSE_STATE || args[0] === constants.RESPONSE_SETSTATE)) {
resolve(args[2]);
} else {
reject('Unknown response: ' + line);
}
socket.destroy();
});
console.log('Sending %s', cmd);
socket.write(cmd + '\r');
})
.on('error', function (err) {
socket.destroy();
reject(err);
});
});
};

Device.prototype.getState = function (module, port) {
const device = this;
return new BluePromise(function (resolve, reject) {
const socket = net.createConnection(constants.PORT_NUMBER, device.getIpAddress());
socket
.on('connect', function () {
const cmd = util.format('%s,%s:%s', constants.COMMAND_GETSTATE, module, port);

rl.createInterface(socket, socket).on('line', function (line) {
console.log('Received (%s): %s', cmd, line);
const args = line.split(',');
if (args.length === 3 && args[0] === constants.RESPONSE_STATE) {
resolve(args[2]);
} else {
reject('Unknown response: ' + line);
}
socket.destroy();
});
console.log('Sending %s', cmd);
socket.write(cmd + '\r');
})
.on('error', function (err) {
socket.destroy();
reject(err);
});
});
};

Device.prototype.sendIR = function (module, port, state) {
const device = this;
return new BluePromise(function (resolve, reject) {
const socket = net.createConnection(constants.PORT_NUMBER, device.getIpAddress());
socket
.on('connect', function () {
const cmd = util.format('%s,%s:%s,%s', constants.COMMAND_SENDIR, module, port, state);

rl.createInterface(socket, socket).on('line', function (line) {
console.log('Received (%s): %s', cmd, line);
const args = line.split(',');
if (args.length === 3 && (args[0] === constants.RESPONSE_IR)) {
resolve(args[2]);
} else {
reject('Unknown response: ' + line);
}
socket.destroy();
});
console.log('Sending %s', cmd);
socket.write(cmd + '\r');
})
.on('error', function (err) {
socket.destroy();
reject(err);
});
});
};

Device.prototype.sendSerial = function (module, serial) {
const device = this;
return new BluePromise(function (resolve, reject) {
const socket = net.createConnection(constants.PORT_NUMBER + module, device.getIpAddress());
socket
.on('connect', function () {
console.log('Sending %s', serial);
socket.write(serial);
socket.destroy();
})
.on('error', function (err) {
socket.destroy();
reject(err);
});
});
};


Loading

0 comments on commit a959049

Please sign in to comment.