First commit of files
This commit is contained in:
parent
c3c7dacda8
commit
c73ee56993
83
SmartHomeNGConnection.js
Executable file
83
SmartHomeNGConnection.js
Executable file
@ -0,0 +1,83 @@
|
|||||||
|
var http = require("http");
|
||||||
|
var WebSocketClient = require('websocket').client
|
||||||
|
|
||||||
|
|
||||||
|
function SmartHomeNGConnection(platform, log, host, port) {
|
||||||
|
this.log = log;
|
||||||
|
this.platform = platform;
|
||||||
|
this.connected = false;
|
||||||
|
this.updateCallback = undefined;
|
||||||
|
this.tomonitor = [];
|
||||||
|
|
||||||
|
this.shng_host = host;
|
||||||
|
this.shng_port = port;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SmartHomeNGConnection.prototype.init = function () {
|
||||||
|
this.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
SmartHomeNGConnection.prototype.connect = function(host, ip) {
|
||||||
|
var that = this
|
||||||
|
this.log("Connecting to SmartHomeNG @ " + this.shng_host);
|
||||||
|
|
||||||
|
this.shng_ws = new WebSocketClient();
|
||||||
|
|
||||||
|
this.shng_ws.connect('ws://' + this.shng_host + ':' + this.shng_port + '/');
|
||||||
|
this.shng_ws.on('connect', function(connection) {
|
||||||
|
that.log('connected to server!');
|
||||||
|
that.connected = true;
|
||||||
|
that.connection = connection;
|
||||||
|
that.startMonitoring();
|
||||||
|
|
||||||
|
connection.on('message', function(message) { that.receive(message); });
|
||||||
|
connection.on('error', function(error) { that.log('WebSocket error: ' + error.toString()) });
|
||||||
|
connection.on('close', function() {
|
||||||
|
that.log('Connection to smarthome lost');
|
||||||
|
that.connected = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SmartHomeNGConnection.prototype.receive = function(message) {
|
||||||
|
var msg = JSON.parse(message.utf8Data);
|
||||||
|
//this.log(msg);
|
||||||
|
if (msg.items) {
|
||||||
|
for (int = 0; int < msg.items.length; int++) {
|
||||||
|
item = msg.items[int];
|
||||||
|
//this.log("Received value " + item[1] + " for item " + item[0]);
|
||||||
|
if (this.updateCallback) {
|
||||||
|
this.updateCallback(item[0], item[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SmartHomeNGConnection.prototype.setValue = function(item, value) {
|
||||||
|
if (this.connected) {
|
||||||
|
this.connection.send('{"cmd":"item","id":"' + item + '","val":"' + value + '"}')
|
||||||
|
} else {
|
||||||
|
this.log("Cannot switch " + item + ", no connection to SmartHomeNG !")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SmartHomeNGConnection.prototype.startMonitoring = function() {
|
||||||
|
if (this.connected && this.tomonitor.length > 0) {
|
||||||
|
var buffer = {};
|
||||||
|
this.log("Start monitoring " + this.tomonitor);
|
||||||
|
buffer.cmd = 'monitor';
|
||||||
|
buffer.items = this.tomonitor;
|
||||||
|
var command = JSON.stringify(buffer);
|
||||||
|
this.connection.send(command);
|
||||||
|
} else {
|
||||||
|
this.log("Cannot start monitoring, not connected !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
SmartHomeNGConnection: SmartHomeNGConnection
|
||||||
|
}
|
||||||
|
|
||||||
212
index.js
Executable file
212
index.js
Executable file
@ -0,0 +1,212 @@
|
|||||||
|
// SmartHomeNG Platform Shim for HomeBridge
|
||||||
|
|
||||||
|
var Accessory, Service, Characteristic, UUIDGen;
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
var SmartHomeNGConnection = require("./SmartHomeNGConnection.js").SmartHomeNGConnection;
|
||||||
|
|
||||||
|
module.exports = function(homebridge) {
|
||||||
|
// Accessory must be created from PlatformAccessory Constructor
|
||||||
|
Accessory = homebridge.platformAccessory;
|
||||||
|
|
||||||
|
// Service and Characteristic are from hap-nodejs
|
||||||
|
Service = homebridge.hap.Service;
|
||||||
|
Characteristic = homebridge.hap.Characteristic;
|
||||||
|
UUIDGen = homebridge.hap.uuid;
|
||||||
|
|
||||||
|
homebridge.registerPlatform("homebridge-smarthomeng", "SmartHomeNG", SmartHomeNGPlatform);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Platform constructor
|
||||||
|
function SmartHomeNGPlatform(log, config, api) {
|
||||||
|
this.log = log;
|
||||||
|
this.config = config;
|
||||||
|
this.accessoriesCache = [];
|
||||||
|
this.supportedFunctions = ['onoff', 'brightness'];
|
||||||
|
|
||||||
|
if (this.config["host"] != undefined) {
|
||||||
|
this.shng_host = this.config["host"];
|
||||||
|
} else {
|
||||||
|
this.shng_host = "localhost";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.config["port"] != undefined) {
|
||||||
|
this.shng_port = this.config["port"];
|
||||||
|
} else {
|
||||||
|
this.shng_port = 2424;
|
||||||
|
}
|
||||||
|
|
||||||
|
var that = this
|
||||||
|
this.log("SmartHomeNG Platform Plugin Version " + this.getVersion())
|
||||||
|
|
||||||
|
this.shngcon = new SmartHomeNGConnection(this, this.log, this.shng_host, this.shng_port);
|
||||||
|
this.shngcon.updateCallback = this.update;
|
||||||
|
|
||||||
|
if (api) {
|
||||||
|
this.api = api;
|
||||||
|
|
||||||
|
// Listen to event "didFinishLaunching", this means homebridge already finished loading cached accessories
|
||||||
|
// Platform Plugin should only register new accessory that doesn't exist in homebridge after this event.
|
||||||
|
// Or start discover new accessories
|
||||||
|
this.api.on('didFinishLaunching', function() {
|
||||||
|
this.log("Finished loading " + this.accessoriesCache.length + " accessories");
|
||||||
|
// Add supported SHNG items to monitoring
|
||||||
|
var tomonitor = [];
|
||||||
|
for(i = 0; i < this.accessoriesCache.length; i++) {
|
||||||
|
var device = this.accessoriesCache[i].device;
|
||||||
|
for (var key in device) {
|
||||||
|
if (this.supportedFunctions.indexOf(key) >= 0) {
|
||||||
|
tomonitor.push(device[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.shngcon.tomonitor = tomonitor;
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.shngcon.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accessory constructor
|
||||||
|
function SmartHomeNGAccessory(log, device, shngcon) {
|
||||||
|
this.name = device.name;
|
||||||
|
this.device = device;
|
||||||
|
this.log = log;
|
||||||
|
this.shngcon = shngcon;
|
||||||
|
this.value = undefined;
|
||||||
|
/*this.log("CONSTRUCTOR: ");
|
||||||
|
this.log(device);
|
||||||
|
this.log("------")*/
|
||||||
|
}
|
||||||
|
|
||||||
|
SmartHomeNGPlatform.prototype = {
|
||||||
|
|
||||||
|
// Return our accessories to homebridge
|
||||||
|
accessories: function(callback) {
|
||||||
|
var that = this;
|
||||||
|
var foundAccessories = [];
|
||||||
|
|
||||||
|
this.log("Building list of accessories");
|
||||||
|
|
||||||
|
var configAccessories = this.config.accessories;
|
||||||
|
for (var i = 0; i < configAccessories.length; i++) {
|
||||||
|
this.log("Parsing accessory: '" + configAccessories[i].name + "'.");
|
||||||
|
|
||||||
|
var accessory = new SmartHomeNGAccessory(that.log, configAccessories[i], that.shngcon);
|
||||||
|
foundAccessories.push(accessory);
|
||||||
|
}
|
||||||
|
|
||||||
|
//this.log(foundAccessories)
|
||||||
|
this.accessoriesCounter = foundAccessories.length;
|
||||||
|
this.accessoriesCache = foundAccessories;
|
||||||
|
callback(foundAccessories);
|
||||||
|
},
|
||||||
|
|
||||||
|
update: function (item, value) {
|
||||||
|
//this.log("CALLBACK: item " + item + " with value " + value);
|
||||||
|
for (i = 0; i < this.platform.accessoriesCache.length; i++) {
|
||||||
|
accessory = this.platform.accessoriesCache[i].device;
|
||||||
|
// loop through accessories and services to find modified one
|
||||||
|
for (var key in accessory) {
|
||||||
|
if (accessory[key] == item) {
|
||||||
|
this.log("Updating item '" + item + "' with value " + value);
|
||||||
|
accessory[key + '_value'] = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Get version info from package.json file
|
||||||
|
getVersion: function() {
|
||||||
|
var pjPath = path.join(__dirname, './package.json');
|
||||||
|
var pj = JSON.parse(fs.readFileSync(pjPath));
|
||||||
|
return pj.version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SmartHomeNGAccessory.prototype = {
|
||||||
|
|
||||||
|
// Enumerate accessory services and characteristics
|
||||||
|
getServices: function() {
|
||||||
|
var that = this;
|
||||||
|
this.log("Setting services for '" + this.name + "'");
|
||||||
|
|
||||||
|
// check if device type is set in config
|
||||||
|
if (!this.device.type) {
|
||||||
|
this.log("Ignoring '" + this.name + "' because no device type found, make sure to have the 'type' parameter in your config.json !");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct service and characteristics according to device type
|
||||||
|
switch (this.device.type.toLowerCase()) {
|
||||||
|
|
||||||
|
// Lightbulb service
|
||||||
|
case 'lightbulb':
|
||||||
|
var myService = new Service.Lightbulb(this.name);
|
||||||
|
// On / Off characteristic
|
||||||
|
if (this.device.onoff) {
|
||||||
|
this.log("Adding on/off characteristic to " + this.name);
|
||||||
|
|
||||||
|
myService
|
||||||
|
.getCharacteristic(Characteristic.On)
|
||||||
|
.on('get', function(callback) { that.getValue("onoff", callback);})
|
||||||
|
.on('set', function(value, callback) { that.setValue("onoff", value, callback);});
|
||||||
|
}
|
||||||
|
// Dimmable characteristic
|
||||||
|
if (this.device.brightness) {
|
||||||
|
this.log("Adding brightness characteristic to " + this.name);
|
||||||
|
myService
|
||||||
|
.addCharacteristic(Characteristic.Brightness)
|
||||||
|
.on('get', function(callback) { that.getValue("brightness", callback);})
|
||||||
|
.on('set', function(value, callback) { that.setValue("brightness", value, callback);});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// If no supported type is found warn user and return empty services
|
||||||
|
default:
|
||||||
|
this.log("Ignoring '" + this.name + "' because device type '" + this.device.type + "' is not supported !");
|
||||||
|
return [];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// device information service
|
||||||
|
var informationService = new Service.AccessoryInformation();
|
||||||
|
informationService
|
||||||
|
.setCharacteristic(Characteristic.Manufacturer, this.manufacturername)
|
||||||
|
.setCharacteristic(Characteristic.Model, this.model)
|
||||||
|
.setCharacteristic(Characteristic.SerialNumber, this.device.uniqueid);
|
||||||
|
|
||||||
|
return [informationService, myService];
|
||||||
|
},
|
||||||
|
|
||||||
|
// Get value
|
||||||
|
getValue: function(characteristic, callback) {
|
||||||
|
this.log("Get value for " + this.device.name + ", characteristic: " + characteristic + ".");
|
||||||
|
//this.log(this.device);
|
||||||
|
if (this.device[characteristic + "_value"] != undefined) {
|
||||||
|
this.log("Found value '" + this.device[characteristic + "_value"] + "' for '" + characteristic + "' of device '" + this.device.name + "'.");
|
||||||
|
if (callback) callback(null, this.device[characteristic + "_value"]);
|
||||||
|
} else {
|
||||||
|
if (callback) callback("Oh oh :-(");
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Set value
|
||||||
|
setValue: function(characteristic, value, callback) {
|
||||||
|
this.log("Set " + this.device.name + ", characteristic: " + characteristic + ", value: " + value + ".");
|
||||||
|
// If item for characteristic exists then send value to it
|
||||||
|
if (this.device[characteristic] != undefined) {
|
||||||
|
this.shngcon.setValue(this.device[characteristic], value);
|
||||||
|
}
|
||||||
|
// Check if callback required
|
||||||
|
if (callback) callback(); // Success
|
||||||
|
callback = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Respond to identify request
|
||||||
|
identify: function(callback) {
|
||||||
|
this.log("Identify request for '" + this.device.name + "'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
20
package.json
Normal file
20
package.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "homebridge-smarthomeng",
|
||||||
|
"version": "1.1.1",
|
||||||
|
"description": "Platform plugin for SmartHomeNG: https://github.com/smarthomeNG/smarthome",
|
||||||
|
"license": "GPL",
|
||||||
|
"keywords": [
|
||||||
|
"homebridge-plugin"
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/example/homebridge.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "http://github.com/example/homebridge/issues"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12.0",
|
||||||
|
"homebridge": ">=0.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user