more cleanups

handle sonos volume caching
added garage door opener
started with homematic keymatic (HM-SEC-KEY)
even more cleanups :)
rgb hue/sat/bri fix
added identify for lightbulbs
This commit is contained in:
Andre Schröter
2015-08-06 10:02:09 +02:00
parent 86322c30c8
commit 7cb835e4ea

View File

@@ -20,17 +20,16 @@ var types = require('HAP-NodeJS/accessories/types.js');
var util = require('util');
// cached readings from longpoll & query
var FHEM_cached = {};
// subscriptions to fhem longpoll evens
var FHEM_subscriptions = {};
function
FHEM_subscribe(characteristic, inform_id, accessory) {
FHEM_subscriptions[inform_id] = { 'characteristic': characteristic, 'accessory': accessory };
//FHEM_subscriptions[inform_id] = characteristic;
}
// cached readings from longpoll & query
var FHEM_cached = {};
//var FHEM_internal = {};
function
FHEM_update(inform_id, value, no_update) {
var subscription = FHEM_subscriptions[inform_id];
@@ -39,6 +38,18 @@ FHEM_update(inform_id, value, no_update) {
|| FHEM_cached[inform_id] === value )
return;
//if( FHEM_internal['.'+subscription.accessory.device+'-homekitID'] == undefined ) {
// var info = subscription.characteristic.accessoryController.tcpServer.accessoryInfo;
// if( info.username ) {
// var accessory = subscription.accessory;
// var cmd = '{$defs{'+ accessory.device +'}->{homekitID} = "'+info.username+'" if(defined($defs{'+ accessory.device +'}));;}';
// //accessory.execute( cmd );
// FHEM_internal['.'+accessory.device+'-homekitID'] = info.username;
// }
//}
FHEM_cached[inform_id] = value;
//FHEM_cached[inform_id] = { 'value': value, 'timestamp': Date.now() };
console.log(" caching: " + inform_id + ": " + value + " as " + typeof(value) );
@@ -118,14 +129,25 @@ function FHEM_startLongpoll(connection) {
continue;
if( reading == 'state') {
if( accessory.isWindow ) {
if( accessory.mappings.window ) {
var level = 50;
if( match = value.match(/^(\d+)/ ) )
level = parseInt( match[1] );
else if( value == 'locked' )
level = 0;
FHEM_update( device+'-level', level );
FHEM_update( accessory.mappings.window.informId, level );
continue;
} else if( accessory.mappings.lock ) {
var lock = 0;
if( value.match( /^locked/ ) )
lock = 1;
if( value.match( /uncertain/ ) )
level = 4;
FHEM_update( accessory.mappings.lock.informId, lock );
continue;
} else if( match = value.match(/dim(\d+)%/ ) ) {
@@ -134,7 +156,7 @@ function FHEM_startLongpoll(connection) {
FHEM_update( device+'-pct', pct );
}
} else if(reading == accessory.hasRGB) {
} else if(accessory.mappings.rgb && reading == accessory.mappings.rgb.reading) {
var hsv = FHEM_rgb2hsv(value);
var hue = parseInt( hsv[0] * 360 );
var sat = parseInt( hsv[1] * 100 );
@@ -354,6 +376,9 @@ FHEMPlatform.prototype = {
} else if( s.Attributes.model == 'HM-SEC-WIN' ) {
accessory = new FHEMAccessory(that.log, that.connection, s);
} else if( s.Attributes.model == 'HM-SEC-KEY' ) {
accessory = new FHEMAccessory(that.log, that.connection, s);
} else if( s.Internals.TYPE == 'PRESENCE' ) {
accessory = new FHEMAccessory(that.log, that.connection, s);
@@ -396,7 +421,7 @@ FHEMAccessory(log, connection, s) {
var match;
if( match = s.PossibleSets.match(/[\^ ]pct\b/) ) {
this.mappings.pct = { reading: 'pct', cmd: 'pct', min: 0, max: 100 };
this.mappings.pct = { reading: 'pct', cmd: 'pct' };
} else if( match = s.PossibleSets.match(/[\^ ]dim\d+%/) ) {
s.hasDim = true;
s.pctMax = 100;
@@ -418,12 +443,12 @@ FHEMAccessory(log, connection, s) {
if( s.PossibleSets.match(/[\^ ]rgb\b/) ) {
s.isLight = true;
s.hasRGB = 'rgb';
this.mappings.rgb = { reading: 'rgb', cmd: 'rgb' };
if( s.Internals.TYPE == 'SWAP_0000002200000003' )
s.hasRGB = '0B-RGBlevel';
this.mappings.rgb = { reading: '0B-RGBlevel', cmd: 'rgb' };
} else if( s.PossibleSets.match(/[\^ ]RGB\b/) ) {
s.isLight = true;
s.hasRGB = 'RGB';
this.mappings.rgb = { reading: 'RGB', cmd: 'RGB' };
}
if( s.Readings['measured-temp'] )
@@ -433,8 +458,11 @@ FHEMAccessory(log, connection, s) {
if( s.Readings.volume )
this.mappings.volume = { reading: 'volume', cmd: 'volume' };
else if( s.Readings.Volume )
this.mappings.volume = { reading: 'Volume', cmd: 'Volume' };
else if( s.Readings.Volume ) {
this.mappings.volume = { reading: 'Volume', cmd: 'Volume', nocache: true };
if( s.Attributes.generateVolumeEvent == 1 )
delete this.mappings.volume.nocache;
}
if( s.Readings.humidity )
this.mappings.humidity = { reading: 'humidity' };
@@ -453,39 +481,48 @@ FHEMAccessory(log, connection, s) {
if( genericType == 'switch' )
s.isSwitch = true;
else if( genericType == 'garage' )
this.mappings.garage = { cmdOpen: 'on', cmdClose: 'off' };
else if( genericType == 'light' )
s.isLight = true;
else if( genericType == 'blind'
|| s.Attributes.subType == 'blindActuator' ) {
s.isBlind = 'pct';
delete this.mappings.pct;
this.mappings.blind = { reading: 'pct', cmd: 'pct' };
} else if( genericType == 'window'
|| s.Attributes.model == 'HM-SEC-WIN' ) {
s.isWindow = 'level';
this.mappings.window = { reading: 'level', cmd: 'level' };
} else if( genericType == 'lock'
|| s.Attributes.model == 'HM-SEC-KEY' ) {
this.mappings.lock = { reading: 'lock' };
} else if( genericType == 'thermostat'
|| s.Attributes.subType == 'thermostat' ) {
s.isThermostat = true;
} else if( s.Internals.TYPE == 'CUL_FHTTK' ) {
s.isContactSensor = 'Window';
this.mappings.contact = { reading: 'Window' };
} else if( s.Attributes.subType == 'threeStateSensor' ) {
s.isContactSensor = 'contact';
this.mappings.contact = { reading: 'contact' };
} else if( s.Internals.TYPE == 'PRESENCE' )
s.isOccupancySensor = true;
this.mappings.occupancy = { reading: 'state' };
else if( s.Attributes.model == 'fs20di' )
s.isLight = true;
if( s.PossibleSets.match(/[\^ ]desired-temp\b/) )
s.isThermostat = 'desired-temp';
this.mappings.thermostat = { reading: 'desired-temp', cmd: 'desired-temp' };
else if( s.PossibleSets.match(/[\^ ]desiredTemperature\b/) )
s.isThermostat = 'desiredTemperature';
this.mappings.thermostat = { reading: 'desiredTemperature', cmd: 'desiredTemperature' };
else if( s.isThermostat ) {
s.isThermostat = false;
delete this.mappings.thermostat;
log( s.Internals.NAME + ' is NOT a thermostat. set for target temperature missing' );
}
@@ -509,20 +546,26 @@ FHEMAccessory(log, connection, s) {
}
}
if( s.isBlind )
log( s.Internals.NAME + ' is blind ['+ s.isBlind +']' );
else if( s.isWindow )
if( this.mappings.door )
log( s.Internals.NAME + ' is door' );
else if( this.mappings.garage )
log( s.Internals.NAME + ' is garage' );
else if( this.mappings.lock )
log( s.Internals.NAME + ' is lock ['+ this.mappings.lock.reading +']' );
else if( this.mappings.window )
log( s.Internals.NAME + ' is window' );
else if( s.isThermostat )
log( s.Internals.NAME + ' is thermostat ['+ s.isThermostat +']' );
else if( s.isContactSensor )
log( s.Internals.NAME + ' is contactsensor [' + s.isContactSensor +']' );
else if( s.isOccupancySensor )
else if( this.mappings.blind )
log( s.Internals.NAME + ' is blind ['+ this.mappings.blind.reading +']' );
else if( this.mappings.thermostat )
log( s.Internals.NAME + ' is thermostat ['+ this.mappings.thermostat.reading +']' );
else if( this.mappings.contact )
log( s.Internals.NAME + ' is contactsensor [' + this.mappings.contact.reading +']' );
else if( this.mappings.occupancy )
log( s.Internals.NAME + ' is occupancysensor' );
else if( s.hasRGB )
log( s.Internals.NAME + ' has RGB [0-' + s.hasRGB +']');
else if( this.mappings.rgb )
log( s.Internals.NAME + ' has RGB [0-' + this.mappings.rgb.reading +']');
else if( this.mappings.pct )
log( s.Internals.NAME + ' is dimable [0-'+ this.mappings.pct.max +']' );
log( s.Internals.NAME + ' is dimable ['+ this.mappings.pct.reading +']' );
else if( s.hasDim )
log( s.Internals.NAME + ' is dimable [0-'+ s.pctMax +']' );
else if( s.isLight )
@@ -530,7 +573,7 @@ FHEMAccessory(log, connection, s) {
else
log( s.Internals.NAME + ' is switchable' );
if( this.hasOnOff )
if( this.hasOnOff )
log( s.Internals.NAME + ' has OnOff [' + this.hasOnOff + ']' );
if( this.mappings.hue )
@@ -573,19 +616,13 @@ FHEMAccessory(log, connection, s) {
this.hasDim = s.hasDim;
this.pctMax = s.pctMax;
this.hasRGB = s.hasRGB;
this.isLight = s.isLight;
this.isBlind = s.isBlind;
this.isWindow = s.isWindow;
this.isThermostat = s.isThermostat;
this.isContactSensor = s.isContactSensor;
this.isOccupancySensor = s.isOccupancySensor;
this.isWindow = s.isWindow;
this.isSwitch = s.isSwitch;
//log( util.inspect(s.Readings) );
if( this.isBlind || this.isDoor || this.isWindow || this.isThermostat )
if( this.mappings.blind || this.mappings.door || this.mappings.garage || this.mappings.window || this.mappings.thermostat )
delete this.mappings.onOff;
var that = this;
@@ -598,7 +635,8 @@ FHEMAccessory(log, connection, s) {
if( value != undefined ) {
var inform_id = that.device +'-'+ reading;
that.mappings[key].informId = inform_id;
FHEM_cached[inform_id] = value;
if( !that.mappings[key].nocache )
FHEM_cached[inform_id] = value;
}
}
} );
@@ -612,10 +650,10 @@ FHEM_dim_values = [ 'dim06%', 'dim12%', 'dim18%', 'dim25%', 'dim31%', 'dim37%',
FHEMAccessory.prototype = {
reading2homekit: function(reading,value) {
if( reading == 'hue' ) {
value = Math.round(value * 360 / this.mappings.hue.max);
value = Math.round(value * 360 / this.mappings.hue ? this.mappings.hue.max : 360);
} else if( reading == 'sat' ) {
value = Math.round(value * 100 / this.mappings.sat.max);
value = Math.round(value * 100 / this.mappings.sat ? this.mappings.sat.max : 100);
} else if( reading == 'pct' ) {
value = parseInt( value );
@@ -628,8 +666,6 @@ FHEMAccessory.prototype = {
else
value = 2;
value = parseInt(value);
} else if(reading == 'motor') {
if( value.match(/^opening/))
value = 1;
@@ -638,16 +674,12 @@ FHEMAccessory.prototype = {
else
value = 2;
value = parseInt(value);
} else if( reading == 'transportState' ) {
if( value == 'PLAYING' )
value = 1;
else
value = 0;
value = parseInt(value);
} else if( reading == 'volume'
|| reading == 'Volume' ) {
value = parseInt( value );
@@ -658,15 +690,20 @@ FHEMAccessory.prototype = {
else
value = 0;
value = parseInt(value);
} else if( reading == 'Window' ) {
if( value.match( /^Closed/ ) )
value = 1;
else
value = 0;
value = parseInt(value);
} else if( reading == 'lock' ) {
if( value.match( /^locked/ ) )
value = 1;
else
value = 0;
if( value.match( /uncertain/ ) )
value = 4;
} else if( reading == 'temperature'
|| reading == 'measured-temp'
@@ -695,13 +732,11 @@ FHEMAccessory.prototype = {
value = 0;
else if( value == '000000' )
value = 0;
else if( value.match( /^[A-D]0$/ ) )
else if( value.match( /^[A-D]0$/ ) ) // FIXME: should be handled by event_map now
value = 0;
else
value = 1;
value = parseInt( value );
}
return(value);
@@ -721,21 +756,14 @@ FHEMAccessory.prototype = {
command: function(c,value) {
this.log(this.name + " sending command " + c + " with value " + value);
if( c == 'on' ) {
if( this.PossibleSets.match(/[\^ ]play\b/i) )
cmd = "set " + this.device + " play";
else if( this.PossibleSets.match(/[\^ ]on\b/) )
cmd = "set " + this.device + " on";
if( c == 'identify' ) {
if( this.type == 'HUEDevice' )
cmd = "set " + this.device + "alert select";
else
this.log(this.name + " Unhandled command! cmd=" + c + ", value=" + value);
cmd = "set " + this.device + " toggle;; sleep 1;; set "+ this.device + " toggle";
} else if( c == 'off' ) {
if( this.PossibleSets.match(/[\^ ]pause\b/i) )
cmd = "set " + this.device + " pause";
else if( this.PossibleSets.match(/[\^ ]off\b/) )
cmd = "set " + this.device + " off";
else
this.log(this.device + " Unhandled command! cmd=" + c + ", value=" + value);
} else if( c == 'set' ) {
cmd = "set " + this.device + " " + value;
} else if( c == 'volume' ) {
cmd = "set " + this.device + " volume " + value;
@@ -776,10 +804,7 @@ FHEMAccessory.prototype = {
value = FHEM_hsv2rgb( h, s, v );
//this.log( this.name + ' rgb : [' + value + ']' );
if( this.PossibleSets.match(/[\^ ]RGB\b/) )
cmd = "set " + this.device + " RGB " + value;
else
cmd = "set " + this.device + " rgb " + value;
cmd = "set " + this.device + " " + this.mappings.rgb.cmd + " " + value;
} else if( c == 'hue' ) {
value = Math.round(value * this.mappings.hue.max / 360);
@@ -790,17 +815,17 @@ FHEMAccessory.prototype = {
cmd = "set " + this.device + " sat " + value;
} else if( c == 'targetTemperature' ) {
cmd = "set " + this.device + " " + this.isThermostat + " " + value;
cmd = "set " + this.device + " " + this.mappings.thermostat.cmd + " " + value;
} else if( c == 'targetPosition' ) {
if( this.isWindow ) {
if( this.mappings.window ) {
if( value == 0 )
value = 'lock';
cmd = "set " + this.device + " level " + value;
cmd = "set " + this.device + " " + this.mappings.window.cmd + " " + value;
} else if( this.isBlind )
cmd = "set " + this.device + " " + this.isBlind + " " + value;
} else if( this.mappings.blind )
cmd = "set " + this.device + " " + this.mappings.blind.cmd + " " + value;
else
this.log(this.name + " Unhandled command! cmd=" + c + ", value=" + value);
@@ -851,19 +876,22 @@ FHEMAccessory.prototype = {
this.log(" not cached" );
var query_reading = reading;
if( reading == 'hue' && !this.mappings.hue && this.hasRGB ) {
query_reading = this.hasRGB;
if( reading == 'hue' && !this.mappings.hue && this.mappings.rgb ) {
query_reading = this.mappings.rgb.reading;
} else if( reading == 'sat' && !this.mappings.sat && this.hasRGB ) {
query_reading = this.hasRGB;
} else if( reading == 'sat' && !this.mappings.sat && this.mappings.rgb ) {
query_reading = this.mappings.rgb.reading;
} else if( reading == 'bri' && !this.mappings.pct && this.hasRGB ) {
query_reading = this.hasRGB;
} else if( reading == 'bri' && !this.mappings.pct && this.mappings.rgb ) {
query_reading = this.mappings.rgb.reading;
} else if( reading == 'pct' && !this.mappings.pct && this.hasDim ) {
query_reading = 'state';
} else if( reading == 'level' && this.isWindow ) {
} else if( reading == 'level' && this.mappings.window ) {
query_reading = 'state';
} else if( reading == 'lock' && this.mappings.lock ) {
query_reading = 'state';
}
@@ -900,17 +928,28 @@ FHEMAccessory.prototype = {
else
value = 50;
} else if(reading == 'hue' && query_reading == that.hasRGB) {
} else if( reading == 'lock'
&& query_reading == 'state') {
if( value.match( /^locked/ ) )
value = 1;
else
value = 0;
if( value.match( /uncertain/ ) )
value = 4;
} else if(reading == 'hue' && query_reading == that.mappings.rgb) {
//FHEM_update( that.device+'-'+query_reading, value );
value = parseInt( FHEM_rgb2hsv(value)[0] * 360 );
} else if(reading == 'sat' && query_reading == that.hasRGB) {
} else if(reading == 'sat' && query_reading == that.mappings.rgb) {
//FHEM_update( that.device+'-'+query_reading, value );
value = parseInt( FHEM_rgb2hsv(value)[1] * 100 );
} else if(reading == 'bri' && query_reading == that.hasRGB) {
} else if(reading == 'bri' && query_reading == that.mappings.rgb) {
//FHEM_update( that.device+'-'+query_reading, value );
value = parseInt( FHEM_rgb2hsv(value)[2] * 100 );
@@ -969,14 +1008,17 @@ FHEMAccessory.prototype = {
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: this.serial ? this.serial : "A1S2NASF88EW",
initialValue: this.serial ? this.serial : "<unknown>",
supportEvents: false,
supportBonjour: false,
manfDescription: "SN",
designedMaxLength: 255
},{
cType: types.IDENTIFY_CTYPE,
onUpdate: null,
onUpdate: function(value) {
if( this.mappings.onOff )
that.command( 'identify' );
},
perms: ["pw"],
format: "bool",
initialValue: false,
@@ -984,8 +1026,7 @@ FHEMAccessory.prototype = {
supportBonjour: false,
manfDescription: "Identify Accessory",
designedMaxLength: 1
}
]
}];
},
controlCharacteristics: function(that) {
@@ -1009,7 +1050,7 @@ FHEMAccessory.prototype = {
FHEM_subscribe(characteristic, that.mappings.onOff.informId, that);
},
onUpdate: function(value) {
that.command( value == 0 ? 'off' : 'on' );
that.command( 'set', value == 0 ? that.mappings.onOff.cmdOff : that.mappings.onOff.cmdOn );
},
onRead: function(callback) {
that.query( that.mappings.onOff.reading, function(state){ callback(state) } );
@@ -1024,7 +1065,7 @@ FHEMAccessory.prototype = {
});
}
if( this.mappings.pct && !this.isBlind ) {
if( this.mappings.pct ) {
cTypes.push({
cType: types.BRIGHTNESS_CTYPE,
onRegister: function(characteristic) {
@@ -1053,6 +1094,7 @@ FHEMAccessory.prototype = {
cType: types.BRIGHTNESS_CTYPE,
onRegister: function(characteristic) {
characteristic.eventEnabled = true;
// state is alreadi subscribed from POWER_STATE_CTYPE
FHEM_subscribe(characteristic, that.name+'-pct', that);
},
onUpdate: function(value) { that.delayed('dim', value); },
@@ -1099,13 +1141,13 @@ FHEMAccessory.prototype = {
designedMinStep: 1,
unit: "arcdegrees"
});
} else if( this.hasRGB ) {
} else if( this.mappings.rgb ) {
cTypes.push({
cType: types.HUE_CTYPE,
onRegister: function(characteristic) {
characteristic.eventEnabled = true;
FHEM_subscribe(characteristic, that.name+'-hue', that);
FHEM_subscribe(characteristic, that.name+'-'+that.hasRGB, that);
FHEM_subscribe(characteristic, that.mappings.rgb.informId, that);
},
onUpdate: function(value) { that.command('H-rgb', value); },
onRead: function(callback) {
@@ -1208,8 +1250,10 @@ FHEMAccessory.prototype = {
cType: types.OUTPUTVOLUME_CTYPE,
onUpdate: function(value) { that.delayed('volume', value); },
onRegister: function(characteristic) {
//characteristic.eventEnabled = true;
//FHEM_subscribe(characteristic, that.mappings.volume.informId, that);
if( !that.mappings.volume.nocache ) {
characteristic.eventEnabled = true;
FHEM_subscribe(characteristic, that.mappings.volume.informId, that);
}
},
onRead: function(callback) {
that.query(that.mappings.volume.reading, function(volume){
@@ -1230,23 +1274,22 @@ FHEMAccessory.prototype = {
});
}
if( this.isBlind ) {
if( this.mappings.blind ) {
cTypes.push({
cType: types.WINDOW_COVERING_TARGET_POSITION_CTYPE,
onUpdate: function(value) { that.delayed('targetPosition', value, 1500); },
//onRegister: function(characteristic) {
// characteristic.eventEnabled = true;
// FHEM_subscribe(characteristic, that.name+'-'+that.isBlind, that);
// FHEM_subscribe(characteristic, that.mappings.blind.informId, that);
//},
onRead: function(callback) {
that.query(that.isBlind, function(pct){
that.query(that.mappings.blind.reading, function(pct){
callback(pct);
});
},
perms: ["pw","pr","ev"],
format: "int",
//initialValue: 100,
initialValue: FHEM_cached[that.device +'-'+ that.isBlind],
initialValue: FHEM_cached[that.mappings.blind.informId],
supportEvents: false,
supportBonjour: false,
manfDescription: "Target Blind Position",
@@ -1259,16 +1302,16 @@ FHEMAccessory.prototype = {
cType: types.WINDOW_COVERING_CURRENT_POSITION_CTYPE,
onRegister: function(characteristic) {
characteristic.eventEnabled = true;
FHEM_subscribe(characteristic, that.name+'-'+that.isBlind, that);
FHEM_subscribe(characteristic, that.mappings.blind.informId, that);
},
onRead: function(callback) {
that.query(that.isBlind, function(pos){
that.query(that.mappings.blind.reading, function(pos){
callback(pos);
});
},
perms: ["pr","ev"],
format: "int",
initialValue: FHEM_cached[that.name+'-'+that.isBlind],
initialValue: FHEM_cached[that.mappings.blind.informId],
supportEvents: true,
supportBonjour: false,
manfDescription: "Current Blind Position",
@@ -1304,16 +1347,12 @@ FHEMAccessory.prototype = {
});
}
if( this.isWindow ) {
if( this.mappings.window ) {
cTypes.push({
cType: types.WINDOW_COVERING_TARGET_POSITION_CTYPE,
onUpdate: function(value) { that.delayed('targetPosition', value, 1500); },
//onRegister: function(characteristic) {
// characteristic.eventEnabled = true;
// FHEM_subscribe(characteristic, that.name+'-'+that.isBlind, that);
//},
onRead: function(callback) {
that.query(that.isWindow, function(level){
that.query(that.mappings.window.reading, function(level){
callback(level);
});
},
@@ -1333,17 +1372,16 @@ FHEMAccessory.prototype = {
onRegister: function(characteristic) {
characteristic.eventEnabled = true;
FHEM_subscribe(characteristic, that.name+'-state', that);
FHEM_subscribe(characteristic, that.name+'-'+that.isWindow, that);
FHEM_subscribe(characteristic, that.mappings.window.informId, that);
},
onRead: function(callback) {
that.query(that.isWindow, function(pos){
that.query(that.mappings.window.reading, function(pos){
callback(pos);
});
},
perms: ["pr","ev"],
format: "int",
initialValue: 50,
//initialValue: FHEM_cached[that.name+'-'+that.isWindow],
initialValue: FHEM_cached[that.mappings.window.informId],
supportEvents: true,
supportBonjour: false,
manfDescription: "Current Window Position",
@@ -1379,23 +1417,75 @@ FHEMAccessory.prototype = {
});
}
if( this.mappings.garage ) {
cTypes.push({
onUpdate: function(value) {
that.command( 'set', value == 0 ? that.mappings.garage.cmdOpen : that.mappings.garage.cmdClose );
},
cType: types.TARGET_DOORSTATE_CTYPE,
onRead: function(callback) {
callback(1);
},
perms: ["pw","pr","ev"],
format: "int",
initialValue: 1,
supportEvents: false,
supportBonjour: false,
manfDescription: "Target GarageDoor Position",
designedMinValue: 0,
designedMaxValue: 1,
designedMinStep: 1,
designedMaxLength: 1
});
cTypes.push({
cType: types.CURRENT_DOOR_STATE_CTYPE,
onRead: function(callback) {
callback(4);
},
perms: ["pr","ev"],
format: "int",
initialValue: 4,
supportEvents: true,
supportBonjour: false,
manfDescription: "Current GarageDoor State",
designedMinValue: 0,
designedMaxValue: 4,
designedMinStep: 1,
designedMaxLength: 1
});
cTypes.push({
cType: types.OBSTRUCTION_DETECTED_CTYPE,
onRead: function(callback) {
callback(false);
},
perms: ["pr","ev"],
format: "bool",
initialValue: 0,
supportEvents: false,
supportBonjour: false,
manfDescription: "Obstruction Detected",
designedMaxLength: 1
});
}
//FIXME: parse range and set designedMinValue & designedMaxValue & designedMinStep
if( this.isThermostat ) {
if( this.mappings.thermostat ) {
cTypes.push({
cType: types.TARGET_TEMPERATURE_CTYPE,
onUpdate: function(value) { that.delayed('targetTemperature', value, 1500); },
onRegister: function(characteristic) {
characteristic.eventEnabled = true;
FHEM_subscribe(characteristic, that.name+'-'+that.isThermostat, that);
FHEM_subscribe(characteristic, that.mappings.thermostat.informId, that);
},
onRead: function(callback) {
that.query(that.isThermostat, function(temperature){
that.query(that.mappings.thermostat.reading, function(temperature){
callback(temperature);
});
},
perms: ["pw","pr","ev"],
format: "float",
initialValue: 20,
initialValue: FHEM_cached[that.mappings.thermostat.informId],
supportEvents: false,
supportBonjour: false,
manfDescription: "Target Temperature",
@@ -1442,21 +1532,21 @@ FHEMAccessory.prototype = {
});
}
if( this.isContactSensor ) {
if( this.mappings.contact ) {
cTypes.push({
cType: types.CONTACT_SENSOR_STATE_CTYPE,
onRegister: function(characteristic) {
characteristic.eventEnabled = true;
FHEM_subscribe(characteristic, that.name+'-'+that.isContactSensor, that);
FHEM_subscribe(characteristic, that.mappings.contact.informId, that);
},
onRead: function(callback) {
that.query(that.isContactSensor, function(state){
that.query(that.mappings.contact.reading, function(state){
callback(state);
});
},
perms: ["pr","ev"],
format: "bool",
initialValue: 0,
initialValue: FHEM_cached[that.mappings.contact.informId],
supportEvents: false,
supportBonjour: false,
manfDescription: "Contact State",
@@ -1464,21 +1554,21 @@ FHEMAccessory.prototype = {
});
}
if( this.isOccupancySensor ) {
if( this.mappings.occupancy ) {
cTypes.push({
cType: types.OCCUPANCY_DETECTED_CTYPE,
onRegister: function(characteristic) {
characteristic.eventEnabled = true;
FHEM_subscribe(characteristic, that.name+'-state', that);
FHEM_subscribe(characteristic, that.mappings.occupancy.informId, that);
},
onRead: function(callback) {
that.query('state', function(state){
that.query(that.mappings.occupancy.reading, function(state){
callback(state);
});
},
perms: ["pr","ev"],
format: "bool",
initialValue: 0,
initialValue: FHEM_cached[that.mappings.occupancy.informId],
supportEvents: false,
supportBonjour: false,
manfDescription: "Occupancy State",
@@ -1541,17 +1631,19 @@ FHEMAccessory.prototype = {
return types.SPEAKER_STYPE;
} else if( this.isSwitch ) {
return types.SWITCH_STYPE;
} else if( this.isBlind ) {
return types.WINDOW_COVERING_STYPE;
} else if( this.isThermostat ) {
return types.THERMOSTAT_STYPE;
} else if( this.isWindow ) {
} else if( this.mappings.garage ) {
return types.GARAGE_DOOR_OPENER_STYPE;
} else if( this.mappings.window ) {
return types.WINDOW_STYPE;
} else if( this.isContactSensor ) {
} else if( this.mappings.blind ) {
return types.WINDOW_COVERING_STYPE;
} else if( this.mappings.thermostat ) {
return types.THERMOSTAT_STYPE;
} else if( this.mappings.contact ) {
return types.CONTACT_SENSOR_STYPE;
} else if( this.isOccupancySensor ) {
} else if( this.mappings.occupancy ) {
return types.OCCUPANCY_SENSOR_STYPE;
} else if( this.isLight || this.mappings.pct || this.mappings.hue || this.hasRGB ) {
} else if( this.isLight || this.mappings.pct || this.mappings.hue || this.mappings.rgb ) {
return types.LIGHTBULB_STYPE;
} else if( this.mappings.temperature ) {
return types.TEMPERATURE_SENSOR_STYPE;
@@ -1591,17 +1683,17 @@ function FHEMdebug_handleRequest(request, response){
//console.log( request );
if( request.url == "/cached" ) {
response.write( "<a href='/'>home</a><br>" );
response.write( "<a href='/'>home</a><br><br>" );
if( FHEM_lastEventTimestamp )
response.write( "FHEM_lastEventTime: "+ new Date(FHEM_lastEventTimestamp) +"<br>" );
response.write( "FHEM_lastEventTime: "+ new Date(FHEM_lastEventTimestamp) +"<br><br>" );
response.end( "cached: " + util.inspect(FHEM_cached).replace(/\n/g, '<br>') );
} else if( request.url == "/subscriptions" ) {
response.write( "<a href='/'>home</a><br>" );
response.write( "<a href='/'>home</a><br><br>" );
response.end( "subscriptions: " + util.inspect(FHEM_subscriptions, {depth: 4}).replace(/\n/g, '<br>') );
} else if( request.url == "/persist" ) {
response.write( "<a href='/'>home</a><br>" );
response.write( "<a href='/'>home</a><br><br>" );
var unique = {};
Object.keys(FHEM_subscriptions).forEach(function(key) {
var characteristic = FHEM_subscriptions[key].characteristic;