Merge branch 'feature/ad2usb' into develop

This commit is contained in:
Alistair Galbraith
2015-07-03 08:33:01 -07:00
6 changed files with 393 additions and 2 deletions

245
accessories/AD2USB.js Normal file
View File

@@ -0,0 +1,245 @@
var types = require("../lib/HAP-NodeJS/accessories/types.js");
var AD2USB = require('ad2usb');
var CUSTOM_PANEL_LCD_TEXT_CTYPE = "A3E7B8F9-216E-42C1-A21C-97D4E3BE52C8";
function AD2USBAccessory(log, config) {
this.log = log;
this.name = config["name"];
this.host = config["host"];
this.port = config["port"];
this.pin = config["pin"];
var that = this;
this.currentArmState = 2;
this.currentStateCharacteristic = undefined;
this.targetStateCharacteristic = undefined;
this.lcdCharacteristic = undefined;
var alarm = AD2USB.connect(this.host, this.port, function() {
// Send an initial empty character to get status
alarm.send('');
// Armed Away
alarm.on('armedAway', function() {
that.log("Armed to AWAY");
if (that.currentStateCharacteristic) {
that.currentStateCharacteristic.updateValue(0, null);
}
if (that.targetStateCharacteristic) {
that.targetStateCharacteristic.updateValue(1, null);
}
});
// Armed Stay
alarm.on('armedStay', function() {
that.log("Armed to STAY");
if (that.currentStateCharacteristic) {
that.currentStateCharacteristic.updateValue(0, null);
}
if (that.targetStateCharacteristic) {
that.targetStateCharacteristic.updateValue(0, null);
}
});
// Armed Night
alarm.on('armedNight', function() {
that.log("Armed to NIGHT");
if (that.currentStateCharacteristic) {
that.currentStateCharacteristic.updateValue(0, null);
}
if (that.targetStateCharacteristic) {
that.targetStateCharacteristic.updateValue(2, null);
}
});
// Disarmed
alarm.on('disarmed', function() {
that.log("Disarmed");
if (that.currentStateCharacteristic) {
that.currentStateCharacteristic.updateValue(1, null);
}
if (that.targetStateCharacteristic) {
that.targetStateCharacteristic.updateValue(3, null);
}
});
// Text Change
alarm.on('lcdtext', function(newText) {
that.log("LCD: " + newText);
if (that.lcdCharacteristic) {
that.lcdCharacteristic.updateValue(newText, null);
}
});
});
this.alarm = alarm;
}
AD2USBAccessory.prototype = {
setArmState: function(targetArmState) {
var that = this;
that.log("Desired target arm state: " + targetArmState);
// TARGET
// 0 - Stay
// 1 - Away
// 2 - Night
// 3 - Disarm
if (targetArmState == 0) {
that.alarm.armStay(that.pin);
}
else if (targetArmState == 1) {
that.alarm.armAway(that.pin);
}
else if (targetArmState == 2) {
that.alarm.armNight(that.pin);
}
else if (targetArmState == 3) {
that.alarm.disarm(that.pin);
}
// CURRENT
// 0 - Armed
// 1 - Disarmed
// 2 - Hold
},
getServices: function() {
var that = this;
return [{
sType: types.ACCESSORY_INFORMATION_STYPE,
characteristics: [{
cType: types.NAME_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: this.name,
supportEvents: false,
supportBonjour: false,
manfDescription: "Name of the accessory",
designedMaxLength: 255
},{
cType: types.MANUFACTURER_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: "Nutech",
supportEvents: false,
supportBonjour: false,
manfDescription: "Manufacturer",
designedMaxLength: 255
},{
cType: types.MODEL_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: "AD2USB",
supportEvents: false,
supportBonjour: false,
manfDescription: "Model",
designedMaxLength: 255
},{
cType: types.SERIAL_NUMBER_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: "AD2USBIF",
supportEvents: false,
supportBonjour: false,
manfDescription: "SN",
designedMaxLength: 255
},{
cType: types.IDENTIFY_CTYPE,
onUpdate: null,
perms: ["pw"],
format: "bool",
initialValue: false,
supportEvents: false,
supportBonjour: false,
manfDescription: "Identify Accessory",
designedMaxLength: 1
}]
},{
sType: types.ALARM_STYPE,
characteristics: [{
cType: types.NAME_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: this.name,
supportEvents: false,
supportBonjour: false,
manfDescription: "Name of service",
designedMaxLength: 255
},{
cType: types.ALARM_CURRENT_STATE_CTYPE,
onUpdate: null,
onRegister: function(characteristic) {
that.currentStateCharacteristic = characteristic;
characteristic.eventEnabled = true;
},
perms: ["pr","ev"],
format: "int",
initialValue: 2,
supportEvents: true,
supportBonjour: false,
manfDescription: "Alarm current arm state",
designedMaxLength: 1
},{
cType: types.ALARM_TARGET_STATE_CTYPE,
onUpdate: function(value) { that.setArmState(value); },
onRegister: function(characteristic) {
that.targetStateCharacteristic = characteristic;
characteristic.eventEnabled = true;
},
perms: ["pw","pr","ev"],
format: "int",
initialValue: 1,
supportEvents: true,
supportBonjour: false,
manfDescription: "Alarm target arm state",
designedMaxLength: 1
},
{
cType: CUSTOM_PANEL_LCD_TEXT_CTYPE,
onUpdate: null,
onRegister: function(characteristic) {
that.lcdCharacteristic = characteristic;
characteristic.eventEnabled = true;
},
perms: ["pr","ev"],
format: "string",
initialValue: "Unknown",
supportEvents: false,
supportBonjour: false,
manfDescription: "Keypad Text",
designedMaxLength: 64
}]
}];
}
};
module.exports.accessory = AD2USBAccessory;

126
accessories/ELKM1.js Normal file
View File

@@ -0,0 +1,126 @@
var types = require("../lib/HAP-NodeJS/accessories/types.js");
var elkington = require("elkington");
function ElkM1Accessory(log, config) {
this.log = log;
this.name = config["name"];
this.zone = config["zone"];
this.host = config["host"];
this.port = config["port"];
this.pin = config["pin"];
this.arm = config["arm"];
}
ElkM1Accessory.prototype = {
setPowerState: function(alarmOn) {
var that = this;
if (!alarmOn)
{
return;
}
var elk = elkington.createConnection({
port: that.port,
host: that.host,
});
switch (that.arm)
{
case 'Away':
elk.armAway({area: that.zone, code: that.pin});
break;
case 'Stay':
elk.armStay({area: that.zone, code: that.pin});
break;
case 'Night':
elk.armNightInstant({area: that.zone, code: that.pin});
break;
default:
break;
}
},
getServices: function() {
var that = this;
return [{
sType: types.ACCESSORY_INFORMATION_STYPE,
characteristics: [{
cType: types.NAME_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: this.name,
supportEvents: false,
supportBonjour: false,
manfDescription: "Name of the accessory",
designedMaxLength: 255
},{
cType: types.MANUFACTURER_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: "Elk",
supportEvents: false,
supportBonjour: false,
manfDescription: "Manufacturer",
designedMaxLength: 255
},{
cType: types.MODEL_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: "M1",
supportEvents: false,
supportBonjour: false,
manfDescription: "Model",
designedMaxLength: 255
},{
cType: types.SERIAL_NUMBER_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: "A1S2NASF88EW",
supportEvents: false,
supportBonjour: false,
manfDescription: "SN",
designedMaxLength: 255
},{
cType: types.IDENTIFY_CTYPE,
onUpdate: null,
perms: ["pw"],
format: "bool",
initialValue: false,
supportEvents: false,
supportBonjour: false,
manfDescription: "Identify Accessory",
designedMaxLength: 1
}]
},{
sType: types.SWITCH_STYPE,
characteristics: [{
cType: types.NAME_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: this.name,
supportEvents: false,
supportBonjour: false,
manfDescription: "Name of service",
designedMaxLength: 255
},{
cType: types.POWER_STATE_CTYPE,
onUpdate: function(value) { that.setPowerState(value); },
perms: ["pw","pr","ev"],
format: "bool",
initialValue: false,
supportEvents: false,
supportBonjour: false,
manfDescription: "Alarm the Zone",
designedMaxLength: 1
}]
}];
}
};
module.exports.accessory = ElkM1Accessory;

1
app.js
View File

@@ -124,6 +124,7 @@ function createHAPServer(name, services) {
for (var k = 0; k < services[j].characteristics.length; k++) {
var options = {
onRead: services[j].characteristics[k].onRead,
onRegister: services[j].characteristics[k].onRegister,
type: services[j].characteristics[k].cType,
perms: services[j].characteristics[k].perms,
format: services[j].characteristics[k].format,

View File

@@ -103,6 +103,23 @@
"off_url": "https://192.168.1.22:3030/devices/23222/off",
"brightness_url": "https://192.168.1.22:3030/devices/23222/brightness/%b",
"http_method": "POST"
},{
"accessory": "ELKM1",
"name": "Security System",
"description": "Allows basic control of Elk M1 security system. You can use 1 of 3 arm modes: Away, Stay, Night. If you need to access all 3, create 3 accessories with different names.",
"zone": "1",
"host": "192.168.1.10",
"port": "2101",
"pin": "1234",
"arm": "Away"
},
{
"accessory": "AD2USB",
"name": "Alarm",
"description": "Arm, disarm, and status monitoring of the default partition for Honeywell/Ademco alarm systems. Requires network configured AD2USB interface",
"host": "192.168.1.200", // IP address of the SER2SOCK service
"port" : 4999, // Port the SER2SOCK process is running on
"pin": "1234" // PIN used for arming / disarming
}
]
}

View File

@@ -10,6 +10,7 @@
"url": "git://github.com/nfarina/homebridge.git"
},
"dependencies": {
"ad2usb": "git+https://github.com/alistairg/node-ad2usb.git#local",
"request": "2.49.x",
"node-persist": "0.0.x",
"xmldoc": "0.1.x",
@@ -18,6 +19,7 @@
"carwingsjs": "0.0.x",
"sonos": "0.8.x",
"wemo": "0.2.x",
"wink-js": "0.0.5"
"wink-js": "0.0.5",
"elkington": "kevinohara80/elkington"
}
}