mirror of
https://github.com/mtan93/homebridge.git
synced 2026-04-16 06:13:10 +01:00
check for hap-nodejs and HAP-NodeJS
allow longpoll to multiple fhem servers increase reconnect timeout after subsequent longpoll disconnect and error added target door state for HM-SEC-KEY -> allows open to be send added current door state to contact sensor -> allows to ask for open windows with siri some cleanups
This commit is contained in:
@@ -14,8 +14,17 @@
|
|||||||
// }
|
// }
|
||||||
// ],
|
// ],
|
||||||
|
|
||||||
var Service = require("HAP-NodeJS").Service;
|
try {
|
||||||
var Characteristic = require("HAP-NodeJS").Characteristic;
|
var Service = require("hap-nodejs").Service;
|
||||||
|
} catch(err) {
|
||||||
|
Service = require("HAP-NodeJS").Service;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var Characteristic = require("HAP-NodeJS").Characteristic;
|
||||||
|
} catch(err) {
|
||||||
|
Characteristic = require("hap-nodejs").Characteristic;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
@@ -66,18 +75,21 @@ FHEM_update(inform_id, value, no_update) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var FHEM_lastEventTime;
|
var FHEM_lastEventTime = {};
|
||||||
var FHEM_longpoll_running = false;
|
var FHEM_longpoll_running = {};
|
||||||
//FIXME: add filter
|
//FIXME: add filter
|
||||||
function FHEM_startLongpoll(connection) {
|
function FHEM_startLongpoll(connection) {
|
||||||
if( FHEM_longpoll_running )
|
if( FHEM_longpoll_running[connection.base_url] )
|
||||||
return;
|
return;
|
||||||
FHEM_longpoll_running = true;
|
FHEM_longpoll_running[connection.base_url] = true;
|
||||||
|
|
||||||
|
if( connection.disconnects == undefined )
|
||||||
|
connection.disconnects = 0;
|
||||||
|
|
||||||
var filter = ".*";
|
var filter = ".*";
|
||||||
var since = "null";
|
var since = "null";
|
||||||
if( FHEM_lastEventTime )
|
if( FHEM_lastEventTime[connection.base_url] )
|
||||||
since = FHEM_lastEventTime/1000;
|
since = FHEM_lastEventTime[connection.base_url]/1000;
|
||||||
var query = "/fhem.pl?XHR=1"+
|
var query = "/fhem.pl?XHR=1"+
|
||||||
"&inform=type=status;filter="+filter+";since="+since+";fmt=JSON"+
|
"&inform=type=status;filter="+filter+";since="+since+";fmt=JSON"+
|
||||||
"×tamp="+Date.now()
|
"×tamp="+Date.now()
|
||||||
@@ -122,7 +134,7 @@ function FHEM_startLongpoll(connection) {
|
|||||||
var subscription = FHEM_subscriptions[d[0]];
|
var subscription = FHEM_subscriptions[d[0]];
|
||||||
if( subscription != undefined ) {
|
if( subscription != undefined ) {
|
||||||
//console.log( "Rcvd: "+(l.length>132 ? l.substring(0,132)+"...("+l.length+")":l) );
|
//console.log( "Rcvd: "+(l.length>132 ? l.substring(0,132)+"...("+l.length+")":l) );
|
||||||
FHEM_lastEventTime = lastEventTime;
|
FHEM_lastEventTime[connection.base_url] = lastEventTime;
|
||||||
var accessory = subscription.accessory;
|
var accessory = subscription.accessory;
|
||||||
|
|
||||||
var value = d[1];
|
var value = d[1];
|
||||||
@@ -227,17 +239,27 @@ function FHEM_startLongpoll(connection) {
|
|||||||
input = input.substr(FHEM_longpollOffset);
|
input = input.substr(FHEM_longpollOffset);
|
||||||
FHEM_longpollOffset = 0;
|
FHEM_longpollOffset = 0;
|
||||||
|
|
||||||
} ).on( 'end', function() {
|
connection.disconnects = 0;
|
||||||
console.log( "longpoll ended" );
|
|
||||||
|
|
||||||
FHEM_longpoll_running = false;
|
} ).on( 'end', function() {
|
||||||
setTimeout( function(){FHEM_startLongpoll(connection)}, 2000 );
|
FHEM_longpoll_running[connection.base_url] = false;
|
||||||
|
|
||||||
|
connection.disconnects++;
|
||||||
|
var timeout = 500 * connection.disconnects - 300;
|
||||||
|
if( timeout > 30000 ) timeout = 30000;
|
||||||
|
|
||||||
|
console.log( "longpoll ended, reconnect in: " + timeout + "msec" );
|
||||||
|
setTimeout( function(){FHEM_startLongpoll(connection)}, timeout );
|
||||||
|
|
||||||
} ).on( 'error', function(err) {
|
} ).on( 'error', function(err) {
|
||||||
console.log( "longpoll error: " + err );
|
FHEM_longpoll_running[connection.base_url] = false;
|
||||||
|
|
||||||
FHEM_longpoll_running = false;
|
connection.disconnects++;
|
||||||
setTimeout( function(){FHEM_startLongpoll(connection)}, 5000 );
|
var timeout = 5000 * connection.disconnects;
|
||||||
|
if( timeout > 30000 ) timeout = 30000;
|
||||||
|
|
||||||
|
console.log( "longpoll error: " + err + ", retry in: " + timeout + "msec" );
|
||||||
|
setTimeout( function(){FHEM_startLongpoll(connection)}, timeout );
|
||||||
|
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
@@ -740,10 +762,12 @@ FHEMAccessory(log, connection, s) {
|
|||||||
this.mappings.window = { reading: 'level', cmd: 'level' };
|
this.mappings.window = { reading: 'level', cmd: 'level' };
|
||||||
|
|
||||||
else if( genericType == 'lock'
|
else if( genericType == 'lock'
|
||||||
|| ( s.Attributes.model && s.Attributes.model.match(/^HM-SEC-KEY/ ) ) )
|
|| ( s.Attributes.model && s.Attributes.model.match(/^HM-SEC-KEY/ ) ) ) {
|
||||||
this.mappings.lock = { reading: 'lock', cmdLock: 'lock', cmdUnlock: 'unlock' };
|
this.mappings.lock = { reading: 'lock', cmdLock: 'lock', cmdUnlock: 'unlock', cmdOpen: 'open' };
|
||||||
|
if( s.Internals.TYPE == 'dummy' )
|
||||||
|
this.mappings.lock = { reading: 'lock', cmdLock: 'lock locked', cmdUnlock: 'lock unlocked', cmdOpen: 'open' };
|
||||||
|
|
||||||
else if( genericType == 'thermostat'
|
} else if( genericType == 'thermostat'
|
||||||
|| s.Attributes.subType == 'thermostat' )
|
|| s.Attributes.subType == 'thermostat' )
|
||||||
s.isThermostat = true;
|
s.isThermostat = true;
|
||||||
|
|
||||||
@@ -1245,27 +1269,6 @@ FHEMAccessory.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
execute: function(cmd,callback) {FHEM_execute(this.log, this.connection, cmd, callback)},
|
execute: function(cmd,callback) {FHEM_execute(this.log, this.connection, cmd, callback)},
|
||||||
executexxx: function(cmd,callback) {
|
|
||||||
var url = encodeURI( this.connection.base_url + "/fhem?cmd=" + cmd + "&XHR=1");
|
|
||||||
this.log( ' executing: ' + url );
|
|
||||||
|
|
||||||
this.connection.request
|
|
||||||
.get( { url: url, gzip: true },
|
|
||||||
function(err, response, result) {
|
|
||||||
if( !err && response.statusCode == 200 ) {
|
|
||||||
if( callback )
|
|
||||||
callback( result );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.log("There was a problem connecting to FHEM ("+ url +").");
|
|
||||||
if( response )
|
|
||||||
this.log( " " + response.statusCode + ": " + response.statusMessage );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}.bind(this) )
|
|
||||||
.on( 'error', function(err) { this.log("There was a problem connecting to FHEM ("+ url +"):"+ err); }.bind(this) );
|
|
||||||
},
|
|
||||||
|
|
||||||
query: function(reading, callback) {
|
query: function(reading, callback) {
|
||||||
if( reading == undefined ) {
|
if( reading == undefined ) {
|
||||||
@@ -1865,6 +1868,26 @@ FHEMAccessory.prototype = {
|
|||||||
.on('get', function(callback) {
|
.on('get', function(callback) {
|
||||||
this.query(this.mappings.lock.reading, callback);
|
this.query(this.mappings.lock.reading, callback);
|
||||||
}.bind(this) );
|
}.bind(this) );
|
||||||
|
|
||||||
|
if( this.mappings.lock.cmdOpen ) {
|
||||||
|
this.log(" target door state characteristic for " + this.name)
|
||||||
|
|
||||||
|
var characteristic = controlService.addCharacteristic(Characteristic.TargetDoorState);
|
||||||
|
|
||||||
|
characteristic.value = Characteristic.TargetDoorState.CLOSED;
|
||||||
|
|
||||||
|
characteristic
|
||||||
|
.on('set', function(characteristic,value, callback, context) {
|
||||||
|
if( context !== 'fromFHEM' ) {
|
||||||
|
this.command( 'set', this.mappings.lock.cmdOpen );
|
||||||
|
setTimeout( function(){characteristic.setValue(Characteristic.TargetDoorState.CLOSED, undefined, 'fromFHEM');}, 500 );
|
||||||
|
}
|
||||||
|
if( callback ) callback();
|
||||||
|
}.bind(this,characteristic) )
|
||||||
|
.on('get', function(callback) {
|
||||||
|
callback(undefined,Characteristic.TargetDoorState.CLOSED);
|
||||||
|
}.bind(this) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( this.mappings.garage ) {
|
if( this.mappings.garage ) {
|
||||||
@@ -1897,6 +1920,7 @@ FHEMAccessory.prototype = {
|
|||||||
}.bind(this) );
|
}.bind(this) );
|
||||||
|
|
||||||
|
|
||||||
|
if( 0 ) {
|
||||||
this.log(" obstruction detected characteristic for " + this.name)
|
this.log(" obstruction detected characteristic for " + this.name)
|
||||||
|
|
||||||
var characteristic = controlService.getCharacteristic(Characteristic.ObstructionDetected);
|
var characteristic = controlService.getCharacteristic(Characteristic.ObstructionDetected);
|
||||||
@@ -1908,6 +1932,7 @@ FHEMAccessory.prototype = {
|
|||||||
.on('get', function(callback) {
|
.on('get', function(callback) {
|
||||||
callback(undefined,1);
|
callback(undefined,1);
|
||||||
}.bind(this) );
|
}.bind(this) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( this.mappings.temperature ) {
|
if( this.mappings.temperature ) {
|
||||||
@@ -2056,6 +2081,19 @@ FHEMAccessory.prototype = {
|
|||||||
.on('get', function(callback) {
|
.on('get', function(callback) {
|
||||||
this.query(this.mappings.contact.reading, callback);
|
this.query(this.mappings.contact.reading, callback);
|
||||||
}.bind(this) );
|
}.bind(this) );
|
||||||
|
|
||||||
|
if( 1 ) {
|
||||||
|
this.log(" current door state characteristic for " + this.name)
|
||||||
|
|
||||||
|
var characteristic = controlService.addCharacteristic(Characteristic.CurrentDoorState);
|
||||||
|
|
||||||
|
characteristic.value = FHEM_cached[this.mappings.contact.informId]==Characteristic.ContactSensorState.CONTACT_DETECTED?Characteristic.CurrentDoorState.CLOSED:Characteristic.CurrentDoorState.OPEN;
|
||||||
|
|
||||||
|
characteristic
|
||||||
|
.on('get', function(callback) {
|
||||||
|
callback(undefined, FHEM_cached[this.mappings.contact.informId]==Characteristic.ContactSensorState.CONTACT_DETECTED?Characteristic.CurrentDoorState.CLOSED:Characteristic.CurrentDoorState.OPEN);
|
||||||
|
}.bind(this) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( this.mappings.occupancy ) {
|
if( this.mappings.occupancy ) {
|
||||||
@@ -2093,7 +2131,9 @@ function FHEMdebug_handleRequest(request, response){
|
|||||||
if( request.url == "/cached" ) {
|
if( request.url == "/cached" ) {
|
||||||
response.write( "<a href='/'>home</a><br><br>" );
|
response.write( "<a href='/'>home</a><br><br>" );
|
||||||
if( FHEM_lastEventTime )
|
if( FHEM_lastEventTime )
|
||||||
response.write( "FHEM_lastEventTime: "+ new Date(FHEM_lastEventTime) +"<br><br>" );
|
var keys = Object.keys(FHEM_lastEventTime);
|
||||||
|
for( var i = 0; i < keys.length; i++ )
|
||||||
|
response.write( "FHEM_lastEventTime " + keys[i] + ": "+ new Date(FHEM_lastEventTime[keys[i]]) +"<br><br>" );
|
||||||
response.end( "cached: " + util.inspect(FHEM_cached).replace(/\n/g, '<br>') );
|
response.end( "cached: " + util.inspect(FHEM_cached).replace(/\n/g, '<br>') );
|
||||||
|
|
||||||
} else if( request.url == "/subscriptions" ) {
|
} else if( request.url == "/subscriptions" ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user