-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
845 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(rc => { | ||
if (rc !== valueToSet) { | ||
throw new Error("State was not correctly set on the device - expecting " + valueToSet + " but got " + rc); | ||
} | ||
}) | ||
.catch(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(state => { | ||
return state !== '0'; | ||
}); | ||
}); | ||
} | ||
|
||
_discoverDevices() { | ||
return discovery | ||
.getDevicePorts(constants.BEACON_TYPE_CC) | ||
.map(port => { | ||
return gcUtils.createDeviceDiscovery(port); | ||
}); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
]; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" } | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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((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', 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', err => { | ||
socket.destroy(); | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
|
||
Device.prototype.setState = function (module, port, state) { | ||
const device = this; | ||
return new BluePromise((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', 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', err => { | ||
socket.destroy(); | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
|
||
Device.prototype.getState = function (module, port) { | ||
const device = this; | ||
return new BluePromise((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', 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', err => { | ||
socket.destroy(); | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
|
||
Device.prototype.sendIR = function (module, port, state) { | ||
const device = this; | ||
return new BluePromise((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', 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', err => { | ||
socket.destroy(); | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
|
||
Device.prototype.sendSerial = function (module, serial) { | ||
const device = this; | ||
return new BluePromise((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', err => { | ||
socket.destroy(); | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
|
||
|
Oops, something went wrong.