mirror of
https://github.com/mtan93/homebridge.git
synced 2026-04-11 14:23:07 +01:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -14,14 +14,21 @@ function HttpAccessory(log, config) {
|
|||||||
this.off_url = config["off_url"];
|
this.off_url = config["off_url"];
|
||||||
this.brightness_url = config["brightness_url"];
|
this.brightness_url = config["brightness_url"];
|
||||||
this.http_method = config["http_method"];
|
this.http_method = config["http_method"];
|
||||||
|
this.username = config["username"];
|
||||||
|
this.password = config["password"];
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpAccessory.prototype = {
|
HttpAccessory.prototype = {
|
||||||
|
|
||||||
httpRequest: function(url, method, callback) {
|
httpRequest: function(url, method, username, password, callback) {
|
||||||
request({
|
request({
|
||||||
url: url,
|
url: url,
|
||||||
method: method
|
method: method,
|
||||||
|
auth: {
|
||||||
|
user: username,
|
||||||
|
pass: password,
|
||||||
|
sendImmediately: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
function (error, response, body) {
|
function (error, response, body) {
|
||||||
callback(error, response, body)
|
callback(error, response, body)
|
||||||
@@ -40,13 +47,17 @@ HttpAccessory.prototype = {
|
|||||||
this.log("Setting power state to off");
|
this.log("Setting power state to off");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.httpRequest(url, this.http_method, function(error, response, body) {
|
this.httpRequest(url, this.http_method, this.username, this.password, function(error, response, body) {
|
||||||
if (error) {
|
if (error) {
|
||||||
this.log('HTTP power function failed: %s', error.message);
|
this.log('HTTP power function failed: %s', error.message);
|
||||||
callback(error);
|
callback(error);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.log('HTTP power function succeeded!');
|
this.log('HTTP power function succeeded!');
|
||||||
|
this.log(response);
|
||||||
|
this.log(body);
|
||||||
|
this.log(this.username);
|
||||||
|
this.log(this.password);
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
@@ -57,7 +68,7 @@ HttpAccessory.prototype = {
|
|||||||
|
|
||||||
this.log("Setting brightness to %s", level);
|
this.log("Setting brightness to %s", level);
|
||||||
|
|
||||||
this.httpRequest(url, this.http_method, function(error, response, body) {
|
this.httpRequest(url, this.http_method, this.username, this.password, function(error, response, body) {
|
||||||
if (error) {
|
if (error) {
|
||||||
this.log('HTTP brightness function failed: %s', error);
|
this.log('HTTP brightness function failed: %s', error);
|
||||||
callback(error);
|
callback(error);
|
||||||
@@ -68,33 +79,33 @@ HttpAccessory.prototype = {
|
|||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
identify: function(callback) {
|
identify: function(callback) {
|
||||||
this.log("Identify requested!");
|
this.log("Identify requested!");
|
||||||
callback(); // success
|
callback(); // success
|
||||||
},
|
},
|
||||||
|
|
||||||
getServices: function() {
|
getServices: function() {
|
||||||
|
|
||||||
// you can OPTIONALLY create an information service if you wish to override
|
// you can OPTIONALLY create an information service if you wish to override
|
||||||
// the default values for things like serial number, model, etc.
|
// the default values for things like serial number, model, etc.
|
||||||
var informationService = new Service.AccessoryInformation();
|
var informationService = new Service.AccessoryInformation();
|
||||||
|
|
||||||
informationService
|
informationService
|
||||||
.setCharacteristic(Characteristic.Manufacturer, "HTTP Manufacturer")
|
.setCharacteristic(Characteristic.Manufacturer, "HTTP Manufacturer")
|
||||||
.setCharacteristic(Characteristic.Model, "HTTP Model")
|
.setCharacteristic(Characteristic.Model, "HTTP Model")
|
||||||
.setCharacteristic(Characteristic.SerialNumber, "HTTP Serial Number");
|
.setCharacteristic(Characteristic.SerialNumber, "HTTP Serial Number");
|
||||||
|
|
||||||
var lightbulbService = new Service.Lightbulb();
|
var lightbulbService = new Service.Lightbulb();
|
||||||
|
|
||||||
lightbulbService
|
lightbulbService
|
||||||
.getCharacteristic(Characteristic.On)
|
.getCharacteristic(Characteristic.On)
|
||||||
.on('set', this.setPowerState.bind(this));
|
.on('set', this.setPowerState.bind(this));
|
||||||
|
|
||||||
lightbulbService
|
lightbulbService
|
||||||
.addCharacteristic(new Characteristic.Brightness())
|
.addCharacteristic(new Characteristic.Brightness())
|
||||||
.on('set', this.setBrightness.bind(this));
|
.on('set', this.setBrightness.bind(this));
|
||||||
|
|
||||||
return [informationService, lightbulbService];
|
return [informationService, lightbulbService];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ function NetAtmoRepository(log, api) {
|
|||||||
|
|
||||||
NetAtmoRepository.prototype = {
|
NetAtmoRepository.prototype = {
|
||||||
refresh: function(callback) {
|
refresh: function(callback) {
|
||||||
var datasource={
|
var datasource = {
|
||||||
devices: {},
|
devices: {},
|
||||||
modules: {}
|
modules: {}
|
||||||
};
|
};
|
||||||
@@ -69,7 +69,7 @@ NetAtmoRepository.prototype = {
|
|||||||
},
|
},
|
||||||
load: function(callback) {
|
load: function(callback) {
|
||||||
var that = this;
|
var that = this;
|
||||||
this.cache.get( "datasource", function( err, datasource ){
|
this.cache.get( "datasource", function( err, datasource ) {
|
||||||
if( !err ){
|
if( !err ){
|
||||||
if ( datasource == undefined ){
|
if ( datasource == undefined ){
|
||||||
that.refresh(callback);
|
that.refresh(callback);
|
||||||
@@ -126,7 +126,14 @@ function NetatmoAccessory(log, repository, deviceId, moduleId, device) {
|
|||||||
if (moduleId) {
|
if (moduleId) {
|
||||||
this.serial = moduleId;
|
this.serial = moduleId;
|
||||||
}
|
}
|
||||||
this.name = device.module_name;
|
|
||||||
|
// add station name to devices to avoid duplicate names
|
||||||
|
if (device.station_name) {
|
||||||
|
this.name = device.station_name + " " + device.module_name;
|
||||||
|
} else {
|
||||||
|
this.name = device.module_name;
|
||||||
|
}
|
||||||
|
|
||||||
this.model = device.type;
|
this.model = device.type;
|
||||||
this.serviceTypes = device.data_type;
|
this.serviceTypes = device.data_type;
|
||||||
if (device.battery_vp) {
|
if (device.battery_vp) {
|
||||||
@@ -161,7 +168,7 @@ NetatmoAccessory.prototype = {
|
|||||||
|
|
||||||
getAirQuality: function(callback) {
|
getAirQuality: function(callback) {
|
||||||
this.getData(function(deviceData) {
|
this.getData(function(deviceData) {
|
||||||
var level = deviceData.dashboard_data.CO2;
|
var level = deviceData.dashboard_data.CO2;
|
||||||
var quality = 0;
|
var quality = 0;
|
||||||
if (level > 2000) quality = 5;
|
if (level > 2000) quality = 5;
|
||||||
else if (level > 1500) quality = 4;
|
else if (level > 1500) quality = 4;
|
||||||
@@ -391,4 +398,4 @@ NetatmoAccessory.prototype = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.exports.accessory = NetatmoAccessory;
|
module.exports.accessory = NetatmoAccessory;
|
||||||
module.exports.platform = NetatmoPlatform;
|
module.exports.platform = NetatmoPlatform;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// OpenHAB Platform Shim for HomeBridge
|
// OpenHAB 1 Platform Shim for HomeBridge
|
||||||
// Written by Tommaso Marchionni
|
// Written by Tommaso Marchionni
|
||||||
// Based on many of the other HomeBridge platform modules
|
// Based on many of the other HomeBridge platform modules
|
||||||
//
|
//
|
||||||
@@ -7,6 +7,9 @@
|
|||||||
// 17 October 2015 [tommasomarchionni]
|
// 17 October 2015 [tommasomarchionni]
|
||||||
// - Initial release
|
// - Initial release
|
||||||
//
|
//
|
||||||
|
// 25 October 2015 [tommasomarchionni]
|
||||||
|
// - Added WS listener and new OOP structure
|
||||||
|
//
|
||||||
// Remember to add platform to config.json. Example:
|
// Remember to add platform to config.json. Example:
|
||||||
// "platforms": [
|
// "platforms": [
|
||||||
// {
|
// {
|
||||||
@@ -23,14 +26,23 @@
|
|||||||
// Switch item=Light_1 label="Light 1"
|
// Switch item=Light_1 label="Light 1"
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
// Rollershutter is tested with this binding in OpenHAB:
|
||||||
|
// command=SWITCH_MULTILEVEL,invert_percent=true,invert_state=false"
|
||||||
// When you attempt to add a device, it will ask for a "PIN code".
|
// When you attempt to add a device, it will ask for a "PIN code".
|
||||||
// The default code for all HomeBridge accessories is 031-45-154.
|
// The default code for all HomeBridge accessories is 031-45-154.
|
||||||
//
|
//
|
||||||
|
|
||||||
var types = require("hap-nodejs/accessories/types.js");
|
//////// LIBS /////////
|
||||||
|
|
||||||
|
var WebSocket = require('ws');
|
||||||
var request = require("request");
|
var request = require("request");
|
||||||
var Service = require("hap-nodejs/lib/Service.js").Service;
|
var Service = require("hap-nodejs/lib/Service.js").Service;
|
||||||
var Characteristic = require("hap-nodejs").Characteristic;
|
var Characteristic = require("hap-nodejs").Characteristic;
|
||||||
|
var currentModule = this;
|
||||||
|
var util = require('core-util-is');
|
||||||
|
util.inherits = require('inherits');
|
||||||
|
|
||||||
|
//////// PLATFORM /////////
|
||||||
|
|
||||||
function OpenhabPlatform(log, config){
|
function OpenhabPlatform(log, config){
|
||||||
this.log = log;
|
this.log = log;
|
||||||
@@ -38,310 +50,524 @@ function OpenhabPlatform(log, config){
|
|||||||
this.password = config["password"];
|
this.password = config["password"];
|
||||||
this.server = config["server"];
|
this.server = config["server"];
|
||||||
this.port = config["port"];
|
this.port = config["port"];
|
||||||
|
|
||||||
this.protocol = "http";
|
this.protocol = "http";
|
||||||
|
|
||||||
this.sitemap = "demo";
|
this.sitemap = "demo";
|
||||||
if (typeof config["sitemap"] != 'undefined') {
|
if (typeof config["sitemap"] != 'undefined') {
|
||||||
this.sitemap = config["sitemap"];
|
this.sitemap = config["sitemap"];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenhabPlatform.prototype = {
|
OpenhabPlatform.prototype = {
|
||||||
|
accessories: function(callback) {
|
||||||
sitemapUrl: function() {
|
|
||||||
var serverString = this.server;
|
|
||||||
//TODO da verificare
|
|
||||||
if (this.user && this.password) {
|
|
||||||
serverString = this.user + ":" + this.password + "@" + serverString;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.protocol + "://" + serverString + ":" + this.port + "/rest/sitemaps/" + this.sitemap + "?type=json";
|
|
||||||
},
|
|
||||||
|
|
||||||
parseSitemap: function(sitemap) {
|
|
||||||
var widgets = [].concat(sitemap.homepage.widget);
|
|
||||||
var result = [];
|
|
||||||
for (var i = 0; i < widgets.length; i++) {
|
|
||||||
var widget = widgets[i];
|
|
||||||
if (!widget.item) {
|
|
||||||
//TODO to handle frame
|
|
||||||
this.log("WARN: The widget '" + widget.label + "' does not reference an item.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (widget.item.type=="SwitchItem" || widget.item.type=="DimmerItem" || widget.item.type == "RollershutterItem"){
|
|
||||||
accessory = new OpenhabAccessory(this.log,this,widget.widgetId,widget.label,widget.item)
|
|
||||||
this.log("Accessory Found: " + widget.label);
|
|
||||||
result.push(accessory);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
accessories: function(callback) {
|
|
||||||
this.log("Fetching OpenHAB devices.");
|
|
||||||
var that = this;
|
var that = this;
|
||||||
|
this.log("Platform - Fetching OpenHAB devices.");
|
||||||
url = that.sitemapUrl();
|
var itemFactory = new ItemFactory(this);
|
||||||
this.log("Connecting to " + url);
|
url = itemFactory.sitemapUrl();
|
||||||
|
this.log("Platform - Connecting to " + url);
|
||||||
request.get({
|
request.get({
|
||||||
url: url,
|
url: url,
|
||||||
json: true
|
json: true
|
||||||
}, function(err, response, json) {
|
}, function(err, response, json) {
|
||||||
if (!err && response.statusCode == 200) {
|
if (!err && response.statusCode == 200) {
|
||||||
callback(that.parseSitemap(json));
|
callback(itemFactory.parseSitemap(json));
|
||||||
} else {
|
} else {
|
||||||
that.log("There was a problem connecting to OpenHAB.");
|
that.log("Platform - There was a problem connecting to OpenHAB.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function OpenhabAccessory(log, platform, widgetId, label, detail) {
|
//////// END PLATFORM /////////
|
||||||
this.log = log;
|
|
||||||
this.platform = platform;
|
///////// ACCESSORY /////////
|
||||||
this.idx = widgetId;
|
|
||||||
this.name = label;
|
function OpenhabAccessory(widget,platform) {}
|
||||||
this.label = label;
|
|
||||||
this.type = detail.type;
|
///////// ABSTRACT ITEM /////////
|
||||||
this.deviceURL = detail.link;
|
|
||||||
this.addressStr = "n/a";
|
function AbstractItem(widget,platform){
|
||||||
this.state = detail.state;
|
|
||||||
|
AbstractItem.super_.call(this,widget,platform);
|
||||||
if (this.type == "DimmerItem") {
|
|
||||||
this.typeSupportsOnOff = true;
|
this.widget = widget;
|
||||||
this.typeSupportsDim = true;
|
this.label = widget.label;
|
||||||
}
|
this.name = widget.item.name;
|
||||||
|
this.url = widget.item.link;
|
||||||
if (this.type == "SwitchItem") {
|
this.state = widget.item.state;
|
||||||
this.typeSupportsOnOff = true;
|
this.platform = platform;
|
||||||
}
|
this.log = platform.log;
|
||||||
|
|
||||||
if (this.type == "RollershutterItem") {
|
|
||||||
this.typeSupportsWindowCovering = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
this.setInitialState = false;
|
||||||
|
this.setFromOpenHAB = false;
|
||||||
|
this.informationService = undefined;
|
||||||
|
this.otherService = undefined;
|
||||||
|
this.listener = undefined;
|
||||||
|
this.ws = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
util.inherits(AbstractItem, OpenhabAccessory);
|
||||||
|
|
||||||
|
AbstractItem.prototype.getInformationServices = function() {
|
||||||
|
informationService = new Service.AccessoryInformation();
|
||||||
|
|
||||||
|
informationService
|
||||||
|
.setCharacteristic(Characteristic.Manufacturer, "OpenHAB")
|
||||||
|
.setCharacteristic(Characteristic.Model, this.constructor.name)
|
||||||
|
.setCharacteristic(Characteristic.SerialNumber, "N/A")
|
||||||
|
.setCharacteristic(Characteristic.Name, this.name);
|
||||||
|
return informationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenhabAccessory.prototype = {
|
AbstractItem.prototype.checkListener = function() {
|
||||||
|
|
||||||
|
if (typeof this.listener == 'undefined' || typeof this.ws == 'undefined') {
|
||||||
|
this.ws = undefined;
|
||||||
|
this.listener = new WSListener(this, this.updateCharacteristics.bind(this));
|
||||||
|
this.listener.startListener();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
updateStatus: function(command) {
|
///////// END ABSTRACT ITEM /////////
|
||||||
var that = this;
|
|
||||||
|
///////// SWITCH ITEM /////////
|
||||||
var options = {
|
|
||||||
url: this.deviceURL,
|
function SwitchItem(widget,platform){
|
||||||
method: 'POST',
|
SwitchItem.super_.call(this, widget,platform);
|
||||||
body: "" + command
|
};
|
||||||
};
|
|
||||||
if (this.auth) {
|
util.inherits(SwitchItem, AbstractItem);
|
||||||
options['auth'] = this.auth;
|
|
||||||
}
|
SwitchItem.prototype.getServices = function() {
|
||||||
|
|
||||||
that.log("eseguo post");
|
this.checkListener();
|
||||||
|
this.setInitialState = true;
|
||||||
request(options, function(error, response, body) {
|
this.informationService = this.getInformationServices();
|
||||||
if (error) {
|
|
||||||
console.trace("Updating Device Status.");
|
|
||||||
that.log(error);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
that.log("updateStatus of " + that.name + ": " + command);
|
|
||||||
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getServiceType: function() {
|
this.otherService = new Service.Lightbulb();
|
||||||
if (this.typeSupportsWindowCovering){
|
this.otherService.getCharacteristic(Characteristic.On)
|
||||||
return new Service.WindowCovering;
|
.on('set', this.setItem.bind(this))
|
||||||
} else if (this.typeSupportsDim) {
|
.on('get', this.getItemPowerState.bind(this))
|
||||||
return new Service.Lightbulb;
|
.setValue(this.state === 'ON');
|
||||||
} else if (this.typeSupportsOnOff) {
|
|
||||||
return new Service.Switch;
|
return [this.informationService, this.otherService];
|
||||||
}
|
};
|
||||||
},
|
|
||||||
|
SwitchItem.prototype.updateCharacteristics = function(message) {
|
||||||
|
|
||||||
|
this.setFromOpenHAB = true;
|
||||||
|
this.otherService
|
||||||
|
.getCharacteristic(Characteristic.On)
|
||||||
|
.setValue(message === 'ON' ? true : false,
|
||||||
|
function() {
|
||||||
|
this.setFromOpenHAB = false;
|
||||||
|
}.bind(this)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
updateStatus: function(command, callback) {
|
SwitchItem.prototype.getItemPowerState = function(callback) {
|
||||||
var that = this;
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
url: this.deviceURL,
|
|
||||||
method: 'POST',
|
|
||||||
body: "" + command
|
|
||||||
};
|
|
||||||
if (this.auth) {
|
|
||||||
options['auth'] = this.auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
request(options, function(error, response, body) {
|
|
||||||
if (error) {
|
|
||||||
//console.trace("Updating Device Status.");
|
|
||||||
//that.log(error);
|
|
||||||
//return error;
|
|
||||||
callback(new Error(error));
|
|
||||||
} else {
|
|
||||||
that.log("updateStatus of " + that.name + ": " + command);
|
|
||||||
callback(true);
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
|
|
||||||
setPowerState: function(powerOn, callback) {
|
var self = this;
|
||||||
var that = this;
|
this.checkListener();
|
||||||
|
|
||||||
|
this.log("iOS - request power state from " + this.name);
|
||||||
|
request(this.url + '/state?type=json', function (error, response, body) {
|
||||||
|
if (!error && response.statusCode == 200) {
|
||||||
|
self.log("OpenHAB HTTP - response from " + self.name + ": " + body);
|
||||||
|
callback(undefined,body == "ON" ? true : false);
|
||||||
|
} else {
|
||||||
|
self.log("OpenHAB HTTP - error from " + self.name + ": " + error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
SwitchItem.prototype.setItem = function(value, callback) {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
this.checkListener();
|
||||||
|
|
||||||
|
if (this.setInitialState) {
|
||||||
|
this.setInitialState = false;
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.setFromOpenHAB) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log("iOS - send message to " + this.name + ": " + value);
|
||||||
|
var command = value ? 'ON' : 'OFF';
|
||||||
|
request.post(
|
||||||
|
this.url,
|
||||||
|
{ body: command },
|
||||||
|
function (error, response, body) {
|
||||||
|
if (!error && response.statusCode == 201) {
|
||||||
|
self.log("OpenHAB HTTP - response from " + self.name + ": " + body);
|
||||||
|
} else {
|
||||||
|
self.log("OpenHAB HTTP - error from " + self.name + ": " + error);
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
///////// END SWITCH ITEM /////////
|
||||||
|
|
||||||
|
///////// DIMMER ITEM /////////
|
||||||
|
|
||||||
|
function DimmerItem(widget,platform){
|
||||||
|
DimmerItem.super_.call(this, widget,platform);
|
||||||
|
};
|
||||||
|
|
||||||
|
util.inherits(DimmerItem, AbstractItem);
|
||||||
|
|
||||||
|
DimmerItem.prototype.getServices = function() {
|
||||||
|
|
||||||
|
this.checkListener();
|
||||||
|
this.setInitialState = true;
|
||||||
|
|
||||||
|
this.informationService = this.getInformationServices();
|
||||||
|
|
||||||
if (this.typeSupportsOnOff) {
|
this.otherService = new Service.Lightbulb();
|
||||||
if (powerOn) {
|
this.otherService.getCharacteristic(Characteristic.On)
|
||||||
var command = "ON";
|
.on('set', this.setItem.bind(this))
|
||||||
} else {
|
.on('get', this.getItemPowerState.bind(this))
|
||||||
var command = "OFF";
|
.setValue(+this.state > 0);
|
||||||
}
|
|
||||||
|
this.setInitialState = true;
|
||||||
this.log("Setting power state on the '"+this.name+"' to " + command);
|
|
||||||
this.updateStatus(command, function(noError){
|
this.otherService.addCharacteristic(Characteristic.Brightness)
|
||||||
if (noError) {
|
.on('set', this.setItem.bind(this))
|
||||||
that.log("Successfully set '"+that.name+"' to " + command);
|
.on('get', this.getItemBrightnessState.bind(this))
|
||||||
callback();
|
.setValue(+this.state);
|
||||||
} else {
|
|
||||||
callback(new Error('Can not communicate with OpenHAB.'));
|
return [this.informationService, this.otherService];
|
||||||
}
|
};
|
||||||
}.bind(this));
|
|
||||||
|
|
||||||
}else{
|
|
||||||
callback(new Error(this.name + " not supports ONOFF"));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getStatus: function(callback){
|
|
||||||
var that = this;
|
|
||||||
this.log("Fetching status brightness for: " + this.name);
|
|
||||||
|
|
||||||
var options = {
|
DimmerItem.prototype.updateCharacteristics = function(message) {
|
||||||
url: this.deviceURL + '/state?type=json',
|
|
||||||
method: 'GET'
|
this.setFromOpenHAB = true;
|
||||||
};
|
var brightness = +message;
|
||||||
|
var steps = 2;
|
||||||
if (this.auth) {
|
if (brightness >= 0) {
|
||||||
options['auth'] = this.auth;
|
this.otherService.getCharacteristic(Characteristic.Brightness)
|
||||||
}
|
.setValue(brightness,
|
||||||
|
function() {
|
||||||
request(options, function(error, response, body) {
|
steps--;
|
||||||
if (error) {
|
if (!steps) {
|
||||||
//console.trace("Requesting Device Status.");
|
this.setFromOpenHAB = false;
|
||||||
//that.log(error);
|
}
|
||||||
//return error;
|
}.bind(this));
|
||||||
callback(new Error('Can not communicate with Home Assistant.'));
|
this.otherService.getCharacteristic(Characteristic.On)
|
||||||
} else {
|
.setValue(brightness > 0 ? true : false,
|
||||||
that.log("getStatus of " + that.name + ": " + body);
|
function() {
|
||||||
callback(null,body);
|
steps--;
|
||||||
}
|
if (!steps) {
|
||||||
|
this.setFromOpenHAB = false;
|
||||||
|
}
|
||||||
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
}
|
||||||
},
|
|
||||||
|
|
||||||
getCurrentPosition: function(callback){
|
|
||||||
callback(100);
|
|
||||||
},
|
|
||||||
|
|
||||||
getPositionState: function(callback){
|
|
||||||
this.log("Fetching position state for: " + this.name);
|
|
||||||
callback(Characteristic.PositionState.STOPPED);
|
|
||||||
},
|
|
||||||
|
|
||||||
setTargetPosition: function(level, callback) {
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
this.log("Setting target position on the '"+this.name+"' to " + level);
|
|
||||||
|
|
||||||
this.updateStatus(level, function(noError){
|
|
||||||
if (noError) {
|
|
||||||
that.log("Successfully set position on the '"+that.name+"' to " + level);
|
|
||||||
callback();
|
|
||||||
} else {
|
|
||||||
callback(new Error('Can not communicate with OpenHAB.'));
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
setBrightness: function(level, callback) {
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
if (this.typeSupportsDim && level >= 0 && level <= 100) {
|
|
||||||
|
|
||||||
this.log("Setting brightness on the '"+this.name+"' to " + level);
|
|
||||||
|
|
||||||
this.updateStatus(level, function(noError){
|
|
||||||
if (noError) {
|
|
||||||
that.log("Successfully set brightness on the '"+that.name+"' to " + level);
|
|
||||||
callback();
|
|
||||||
} else {
|
|
||||||
callback(new Error('Can not communicate with OpenHAB.'));
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getServices: function() {
|
|
||||||
|
|
||||||
var informationService = new Service.AccessoryInformation();
|
|
||||||
|
|
||||||
informationService
|
|
||||||
.setCharacteristic(Characteristic.Manufacturer, "OpenHAB")
|
|
||||||
.setCharacteristic(Characteristic.Model, this.type)
|
|
||||||
.setCharacteristic(Characteristic.SerialNumber, "1234567890")
|
|
||||||
.setCharacteristic(Characteristic.Name, this.label);
|
|
||||||
|
|
||||||
var otherService = this.getServiceType();
|
|
||||||
|
|
||||||
if (this.typeSupportsOnOff) {
|
|
||||||
otherService
|
|
||||||
.getCharacteristic(Characteristic.On)
|
|
||||||
.on('get', this.getStatus.bind(this))
|
|
||||||
.on('set', this.setPowerState.bind(this));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.typeSupportsDim) {
|
|
||||||
otherService
|
|
||||||
.addCharacteristic(Characteristic.Brightness)
|
|
||||||
.on('get', this.getStatus.bind(this))
|
|
||||||
.on('set', this.setBrightness.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.typeSupportsWindowCovering) {
|
|
||||||
var currentPosition = 100;
|
|
||||||
|
|
||||||
otherService
|
|
||||||
.getCharacteristic(Characteristic.CurrentPosition)
|
|
||||||
.on('get', this.getCurrentPosition.bind(this))
|
|
||||||
.setValue(currentPosition);
|
|
||||||
|
|
||||||
otherService
|
|
||||||
.getCharacteristic(Characteristic.PositionState)
|
|
||||||
.on('get', this.getPositionState.bind(this))
|
|
||||||
.setValue(Characteristic.PositionState.STOPPED);
|
|
||||||
|
|
||||||
otherService
|
|
||||||
.getCharacteristic(Characteristic.TargetPosition)
|
|
||||||
.on('get', this.getCurrentPosition.bind(this))
|
|
||||||
.on('set', this.setTargetPosition.bind(this));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(informationService);
|
|
||||||
|
|
||||||
return [informationService, otherService];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DimmerItem.prototype.getItemPowerState = function(callback) {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
this.checkListener();
|
||||||
|
|
||||||
|
this.log("iOS - request power state from " + this.name);
|
||||||
|
request(this.url + '/state?type=json', function (error, response, body) {
|
||||||
|
if (!error && response.statusCode == 200) {
|
||||||
|
self.log("OpenHAB HTTP - response from " + self.name + ": " + body);
|
||||||
|
callback(undefined,+body > 0 ? true : false);
|
||||||
|
} else {
|
||||||
|
self.log("OpenHAB HTTP - error from " + self.name + ": " + error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
DimmerItem.prototype.setItem = function(value, callback) {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
this.checkListener();
|
||||||
|
|
||||||
|
if (this.setInitialState) {
|
||||||
|
this.setInitialState = false;
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.setFromOpenHAB) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log("iOS - send message to " + this.name + ": " + value);
|
||||||
|
var command = 0;
|
||||||
|
if (typeof value === 'boolean') {
|
||||||
|
command = value ? '100' : '0';
|
||||||
|
} else {
|
||||||
|
command = "" + value;
|
||||||
|
}
|
||||||
|
request.post(
|
||||||
|
this.url,
|
||||||
|
{
|
||||||
|
body: command,
|
||||||
|
headers: {'Content-Type': 'text/plain'}
|
||||||
|
},
|
||||||
|
function (error, response, body) {
|
||||||
|
if (!error && response.statusCode == 201) {
|
||||||
|
self.log("OpenHAB HTTP - response from " + self.name + ": " + body);
|
||||||
|
} else {
|
||||||
|
self.log("OpenHAB HTTP - error from " + self.name + ": " + error);
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
DimmerItem.prototype.getItemBrightnessState = function(callback) {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
this.log("iOS - request brightness state from " + this.name);
|
||||||
|
request(this.url + '/state?type=json', function (error, response, body) {
|
||||||
|
if (!error && response.statusCode == 200) {
|
||||||
|
self.log("OpenHAB HTTP - response from " + self.name + ": " + body);
|
||||||
|
callback(undefined,+body);
|
||||||
|
} else {
|
||||||
|
self.log("OpenHAB HTTP - error from " + self.name + ": " + error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
///////// END DIMMER ITEM /////////
|
||||||
|
|
||||||
|
///////// ROLLERSHUTTER ITEM /////////
|
||||||
|
|
||||||
|
function RollershutterItem(widget,platform){
|
||||||
|
RollershutterItem.super_.call(this, widget,platform);
|
||||||
|
this.positionState = Characteristic.PositionState.STOPPED;
|
||||||
|
this.currentPosition = 100;
|
||||||
|
this.targetPosition = 100;
|
||||||
|
this.startedPosition = 100;
|
||||||
|
};
|
||||||
|
|
||||||
|
util.inherits(RollershutterItem, AbstractItem);
|
||||||
|
|
||||||
|
RollershutterItem.prototype.getServices = function() {
|
||||||
|
|
||||||
|
this.checkListener();
|
||||||
|
|
||||||
|
this.informationService = this.getInformationServices();
|
||||||
|
|
||||||
|
this.otherService = new Service.WindowCovering();
|
||||||
|
|
||||||
|
this.otherService.getCharacteristic(Characteristic.CurrentPosition)
|
||||||
|
.on('get', this.getItemCurrentPosition.bind(this))
|
||||||
|
.setValue(this.currentPosition);
|
||||||
|
|
||||||
|
this.setInitialState = true;
|
||||||
|
|
||||||
|
this.otherService.getCharacteristic(Characteristic.TargetPosition)
|
||||||
|
.on('set', this.setItem.bind(this))
|
||||||
|
.on('get', this.getItemTargetPosition.bind(this))
|
||||||
|
.setValue(this.currentPosition);
|
||||||
|
|
||||||
|
this.otherService.getCharacteristic(Characteristic.PositionState)
|
||||||
|
.on('get', this.getItemPositionState.bind(this))
|
||||||
|
.setValue(this.positionState);
|
||||||
|
|
||||||
|
return [this.informationService, this.otherService];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RollershutterItem.prototype.updateCharacteristics = function(message) {
|
||||||
|
|
||||||
|
console.log(message);
|
||||||
|
console.log(this.targetPosition);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (parseInt(message) == this.targetPosition) {
|
||||||
|
var ps = Characteristic.PositionState.STOPPED;
|
||||||
|
var cs = parseInt(message);
|
||||||
|
} else if (parseInt(message) > this.targetPosition){
|
||||||
|
var ps = Characteristic.PositionState.INCREASING;
|
||||||
|
var cs = this.startedPosition;
|
||||||
|
} else {
|
||||||
|
var ps = Characteristic.PositionState.DECREASING;
|
||||||
|
var cs = this.startedPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.otherService
|
||||||
|
.getCharacteristic(Characteristic.PositionState)
|
||||||
|
.setValue(ps);
|
||||||
|
|
||||||
|
this.otherService
|
||||||
|
.getCharacteristic(Characteristic.CurrentPosition)
|
||||||
|
.setValue(parseInt(cs));
|
||||||
|
this.currentPosition = parseInt(cs);
|
||||||
|
};
|
||||||
|
|
||||||
|
RollershutterItem.prototype.setItem = function(value, callback) {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
this.checkListener();
|
||||||
|
|
||||||
|
if (this.setInitialState) {
|
||||||
|
this.setInitialState = false;
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.startedPosition = this.currentPosition;
|
||||||
|
|
||||||
|
this.log("iOS - send message to " + this.name + ": " + value);
|
||||||
|
|
||||||
|
var command = 0;
|
||||||
|
if (typeof value === 'boolean') {
|
||||||
|
command = value ? '100' : '0';
|
||||||
|
} else {
|
||||||
|
command = "" + value;
|
||||||
|
}
|
||||||
|
request.post(
|
||||||
|
this.url,
|
||||||
|
{
|
||||||
|
body: command,
|
||||||
|
headers: {'Content-Type': 'text/plain'}
|
||||||
|
},
|
||||||
|
function (error, response, body) {
|
||||||
|
if (!error && response.statusCode == 201) {
|
||||||
|
self.log("OpenHAB HTTP - response from " + self.name + ": " + body);
|
||||||
|
self.targetPosition = parseInt(value);
|
||||||
|
} else {
|
||||||
|
self.log("OpenHAB HTTP - error from " + self.name + ": " + error);
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
RollershutterItem.prototype.getItemPositionState = function(callback) {
|
||||||
|
this.log("iOS - request position state from " + this.name);
|
||||||
|
this.log("Platform - response from " + this.name + ": " + this.positionState);
|
||||||
|
callback(undefined,this.positionState);
|
||||||
|
};
|
||||||
|
|
||||||
|
RollershutterItem.prototype.getItemTargetPosition = function(callback) {
|
||||||
|
this.log("iOS - get target position state from " + this.name);
|
||||||
|
this.log("Platform - response from " + this.name + ": " + this.targetPosition);
|
||||||
|
callback(undefined,this.targetPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
RollershutterItem.prototype.getItemCurrentPosition = function(callback) {
|
||||||
|
var self = this;
|
||||||
|
this.log("iOS - request current position state from " + this.name);
|
||||||
|
|
||||||
|
request(this.url + '/state?type=json', function (error, response, body) {
|
||||||
|
if (!error && response.statusCode == 200) {
|
||||||
|
|
||||||
|
self.log("OpenHAB HTTP - response from " + self.name + ": " +body);
|
||||||
|
self.currentPosition = parseInt(body);
|
||||||
|
callback(undefined,parseInt(body));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
self.log("OpenHAB HTTP - error from " + self.name + ": " + error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
///////// END ROLLERSHUTTER ITEM /////////
|
||||||
|
|
||||||
|
///////// ITEM UTILITY /////////
|
||||||
|
|
||||||
|
function ItemFactory(openhabPlatform){
|
||||||
|
this.platform = openhabPlatform;
|
||||||
|
this.log = this.platform.log;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemFactory.prototype = {
|
||||||
|
sitemapUrl: function() {
|
||||||
|
var serverString = this.platform.server;
|
||||||
|
//TODO da verificare
|
||||||
|
if (this.platform.user && this.platform.password) {
|
||||||
|
serverString = this.platform.user + ":" + this.platform.password + "@" + serverString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.platform.protocol + "://" + serverString + ":" + this.platform.port + "/rest/sitemaps/" + this.platform.sitemap + "?type=json";
|
||||||
|
},
|
||||||
|
|
||||||
|
parseSitemap: function(jsonSitemap) {
|
||||||
|
var widgets = [].concat(jsonSitemap.homepage.widget);
|
||||||
|
|
||||||
|
var result = [];
|
||||||
|
for (var i = 0; i < widgets.length; i++) {
|
||||||
|
var widget = widgets[i];
|
||||||
|
if (!widget.item) {
|
||||||
|
//TODO to handle frame
|
||||||
|
this.log("Platform - The widget '" + widget.label + "' is not an item.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentModule[widget.item.type] != undefined) {
|
||||||
|
var accessory = new currentModule[widget.item.type](widget,this.platform);
|
||||||
|
} else {
|
||||||
|
this.log("Platform - The widget '" + widget.label + "' of type "+widget.item.type+" is an item not handled.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log("Platform - Accessory Found: " + widget.label);
|
||||||
|
result.push(accessory);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
///////// END ITEM UTILITY /////////
|
||||||
|
|
||||||
|
///////// WS LISTENER /////////
|
||||||
|
|
||||||
|
function WSListener(item, callback){
|
||||||
|
this.item = item;
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
WSListener.prototype = {
|
||||||
|
startListener: function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (typeof this.item.ws == 'undefined') {
|
||||||
|
this.item.ws = new WebSocket(this.item.url.replace('http:', 'ws:') + '/state?type=json');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.item.ws.on('open', function() {
|
||||||
|
self.item.log("OpenHAB WS - new connection for "+self.item.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.item.ws.on('message', function(message) {
|
||||||
|
self.item.log("OpenHAB WS - message from " +self.item.name+": "+ message);
|
||||||
|
self.callback(message);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.item.ws.on('close', function close() {
|
||||||
|
self.item.log("OpenHAB WS - closed connection for "+self.item.name);
|
||||||
|
self.item.listener = undefined;
|
||||||
|
self.item.ws = undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
///////// END WS LISTENER /////////
|
||||||
|
|
||||||
|
///////// SUPPORTED ITEMS /////////
|
||||||
|
module.exports.SwitchItem = SwitchItem;
|
||||||
|
module.exports.DimmerItem = DimmerItem;
|
||||||
|
module.exports.RollershutterItem = RollershutterItem;
|
||||||
|
///////// END SUPPORTED ITEMS /////////
|
||||||
|
|
||||||
module.exports.accessory = OpenhabAccessory;
|
module.exports.accessory = OpenhabAccessory;
|
||||||
module.exports.platform = OpenhabPlatform;
|
module.exports.platform = OpenhabPlatform;
|
||||||
|
|||||||
Reference in New Issue
Block a user